Android 四大组件 Activity、Service、Broadcast、Content Provider
一、Android四大组件
Activity、Service、Broadcast、Content Provider
1、Activity:
1.1、打开App内部Activity:
Intent intent = new Intent(SourceActivity.this,TargetActivity.class); startActivity(intent);
1.2、打开Activity并获取返回结果(类似模式对话框):
主Activity:
public class MainActivity extends Activity { ...... //在Activity的某个按钮的监听方法中 Intent intent=new Intent(this, OtherActivity.class); int rCode = 1 //启动需要监听返回值的Activity,并设置请求码:requestCode startActivityForResult(intent, rCode); ...... @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //当otherActivity中返回数据的时候,会响应此方法 //requestCode和resultCode必须与请求startActivityForResult()和返回setResult()的时候传入的值一致。 if(requestCode==rCode && resultCode==2) { int num=data.getIntExtra("result", 0); } }
OtherActivity:
public class otherActivity extends Activity { ....... //新声明一个Intent用于存放放回的数据 Intent i=new Intent(); int result=100; i.putExtra("data", result); int resultCode = 2; setResult(resultCode, i);//设置resultCode,onActivityResult()中能获取到 finish();//使用完成后结束当前Activity的生命周期 ...... }
注意:
RequestCode:当Activity中需要打开多个Activity来处理不同业务并要获取结果时,在当前Activity的onActivityResult中RequestCode可用来区分不同业务Activity。如 你(MainActivity)需要装修房子,你找水电工(Activity1)、瓷砖工(Activity2)、粉刷匠(Activity3)来干活(他们干活的过程中,你不会在现场),因为你感觉没必要这些工人的姓名,所以你就给他们每个人分配了一个工号(1、2、3,注意:这里的1、2、3是你定义的),让他们干完活后电话告诉你结果时报工号。当你接到工人电话时(onActivityResult),收到工号1(RequestCode)你就知道是水电工干完工作了。
ResultCode:当被打开的Activity可以执行多个业务功能时,反应不同业务的执行结果时,需要在被打开的Activity中 设置ResultCode来区分不同的业务。如:上述装修的例子,你找的瓷砖工也会粉刷,贴瓷砖、刷墙他一人都帮你干了。这时唯一的工号就无法区分他的贴瓷砖、刷墙这2个业务(你接到电话:老板,2号干完了。贴瓷砖干完了?刷墙干完了?还是都干完?)。为了避免上述情况的发生,2号工人跟你约定:干完电话通知你,报工号同时报100表示贴瓷砖结束,报101表示刷墙结束(注意:这里的100、101是工人定义的)。当你接到工人电话时(onActivityResult),收到工号2(RequestCode)、结果号101(ResultCode),你就知道是2号工人刷墙完成了。
1.3、打开其他App:
Intent intent = new Intent(); intent.setClassName("B应用包名", "B应用包名.Activity");
2、Service:
2.1、startService():用于启动后台长期服务。Service进入started状态后,除非Service自己调用stopSelf()或其他组件调用stopService()来停止。
public class MyService extends Service { @Override public void onCreate() { } public class MyThread extends Thread{ @Override public void run() { while(true){ try { sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } Message msg = new Message(); msg.what = 100; handler.sendMessage(msg); } } } Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case 100: Toast.makeText(MyService.this, "service running", Toast.LENGTH_SHORT).show(); break; default: break; } } }; @Override public IBinder onBind(Intent intent) { return null; } }
//启动service Intent intent = new Intent(); intent.setClass(MainActivity.this, MyService.class); startService(intent);
//设置在MyService在单独的进程中运行(进程名称为:App-packageName:remote) <service android:name=".MyService" android:process=":test" />
2.2、bindService():使用ServiceConnection将调用者与Service绑定在一起,一旦调用者终止,Service也将终止。在这类Service中处理耗时工作时,应该使用新的线程。
public class MyService extends Service { @Override public void onCreate() { } public class MyThread extends Thread{ @Override public void run() { while(true){ try { sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } Message msg = new Message(); msg.what = 100; handler.sendMessage(msg); } } } Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case 100: Toast.makeText(MyService.this, "service running", Toast.LENGTH_SHORT).show(); break; default: break; } } }; /** * 返回一个Binder对象 */ @Override public IBinder onBind(Intent intent) { return new MsgBinder(); } public class MsgBinder extends Binder{ /** * 获取当前Service的实例 * @return */ public MsgService getService(){ return MsgService.this; } } }
//在Activity中创建ServiceConnection对象
ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //使用myService来引用返回一个Service对象 msgService = ((MsgService.MsgBinder)service).getService(); } };
//Activity中绑定Service
public class MainActivity extends Activity { private MsgService msgService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定Service Intent intent = new Intent(this,MyService.class); bindService(intent, conn, Context.BIND_AUTO_CREATE); } ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //返回一个MsgService对象 msgService = ((MsgService.MsgBinder)service).getService(); } }; @Override protected void onDestroy() { unbindService(conn); super.onDestroy(); } }
3、Broadcast:
Broadcast广播是Android 系统中的一种数据(消息)传输方式,
类似于电台广播节目(消息),以特定的调频 FM90.7(Intent的Action)广播出去。只要在信号覆盖范围内(Android手机内),拥有收音机(BroadcastReceiver)的人(Android手机内的App);只要将收音机调频到 FM90.7(IntentFilter的Action),都能听到广播的节目(消息)。
在Android系统中内置了非常多的广播,如:SIM卡插拔、电池电量变化、WIFI状态变化等等。这些都属于系统广播,类似于政府开设的各种电台。普通人是否也能开个电台给广大人民群众”普普法“呢?现实生活中可能有难度,但Android就随便你了(自定义广播)。
3.1、创建并注册BroadcastReceiver,接收广播
创建MyReceiver
public class MyReceiver extends BroadcastReceiver { public MyReceiver() { } @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"接收广播",Toast.LENGTH_SHORT).show(); } }
静态注册或动态注册MyReceiver
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.example.dw039.test"/> </intent-filter> </receiver>
//动态注册 public class MainActivity extends Activity { private MyReceiver myReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myReceiver = new MyReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("com.example.com.dw039.test"); registerReceiver(myReceiver, intentFilter); } ...... unregisterReceiver(myReceiver); ...... }
3.2、sendBroadcast();
发布标准广播:
Intent intent=new Intent("com.example.dw039.test"); intent.putExtra("key","key"); sendBroadcast(intent);
3.3、sendOrederBroadcast();
发布有序广播:这种广播,在有多个BroadcastReceiver接收者时,会按接收者的优先级高低依次收到广播;接收器收到广播后,可处理并传递数据到下一个接收器或终止广播的向下传递。
public class MyReceiver extends BroadcastReceiver { public MyReceiver() { } @Override public void onReceive(Context context, Intent intent) { //处理广播 Bundle bundle= getResultExtras(true); //getResultExtras获取前一个接收者传递的Bundle,true表示如果前一个接收者没有转递Bundle,就new一个;false则表示在没有传递Bundle的情况下返回null bundle.putString("msg","处理过后的广播"); setResultExtras(bundle);//向下一个接收者传递数据 //终止广播向下传递 abortBroadcast(); }
Intent intent=new Intent("com.example.dw039.test"); intent.putExtra("key","key"); //null为权限字符串,为null则仅使用Action来匹配广播接收器,否则该字符串也将参与广播接收器的匹配。其实就相当于收音机要收听FM90.3,还要进行口令校验 sendOrderBroadcast(intent,null);
<receiver android:name=".MyReiceiver"> <intent-filter android:priority="10">//添加级别 <action android:name="com.example.dw039.test" /> </intent-filter> </receiver>
3.4、sendStickyBroadcast():在android9 API 21中被标记为过时的
4、Content Provider:内容提供者,主要用于app间共享数据。
因为我们的App一般规模较小且数据都是私有的,所以实际开发中使用它的机会不多。其原理类似于JDBC,Content Provider也提供了标准的数据存取功能接口(类)。如果你的App要给其他App提供数据,只要按照规范重写ContentProvider的相关方法。相反的如果你的App要获取其他App共享的数据,只要按照规范重写ContentResolver的相关方法。
具体实现自行搜索
作者:DW039
出处:http://www.cnblogs.com/dw039
本文由DW039原创并发布于博客园,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。