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的相关方法。
具体实现自行搜索

 

posted @ 2024-07-13 22:41  DW039  阅读(32)  评论(0编辑  收藏  举报