Android组件之间的通信

来源:互联网 发布:淘宝五个金冠 编辑:程序博客网 时间:2024/06/01 18:18

1.三大组件之间:Activity, Services,Broadcast receivers 的通信是通过intents传递。

2.Activity 和 activity之间:通过方法startActivity()可以从一个activity中开启另外一个activity。

Intent intent = new Intent(this, SignInActivity.class);startActivity(intent);

当想从开启的activity中获取一些数据,那么可以调用 startActivityForResult()开启另外一个activity。为了接收这个被开启的activity传递过来的数据,需要在原来的activity中回调 onActivityResult()。被开启的activity会通过onActivityResult()传递一个intent。

private void pickContact() {    // Create an intent to "pick" a contact, as defined by the content provider URI    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);    startActivityForResult(intent, PICK_CONTACT_REQUEST);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {        // Perform a query to the contact's content provider for the contact's name        Cursor cursor = getContentResolver().query(data.getData(),        new String[] {Contacts.DISPLAY_NAME}, null, null, null);        if (cursor.moveToFirst()) { // True if the cursor is not empty            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);            String name = cursor.getString(columnIndex);            // Do something with the selected contact's name...        }    }}

3.Service和组件的通信:组件可以通过StartService或是BindService,或是IPC来交互。

public class HelloService extends Service {  private Looper mServiceLooper;  private ServiceHandler mServiceHandler;  // 处理从线程返回来的消息  private final class ServiceHandler extends Handler {      public ServiceHandler(Looper looper) {          super(looper);      }      @Override      public void handleMessage(Message msg) {         //这里睡眠5s          long endTime = System.currentTimeMillis() + 5*1000;          while (System.currentTimeMillis() < endTime) {              synchronized (this) {                  try {                      wait(endTime - System.currentTimeMillis());                  } catch (Exception e) {                  }              }          }          // 用startId停止服务          // the service in the middle of handling another job          stopSelf(msg.arg1);      }  }  @Override  public void onCreate() {    // 开启线程运行服务    HandlerThread thread = new HandlerThread("ServiceStartArguments",            Process.THREAD_PRIORITY_BACKGROUND);    thread.start();    // 获取轮询器    mServiceLooper = thread.getLooper();    mServiceHandler = new ServiceHandler(mServiceLooper);  }  @Override  public int onStartCommand(Intent intent, int flags, int startId) {      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();    //每一次的开启请求,都会发一个消息来开始工作和传递start ID,这样当我们完成工作之后,就知道应该要停止哪个请求      Message msg = mServiceHandler.obtainMessage();      msg.arg1 = startId;      mServiceHandler.sendMessage(msg);      // 如果被杀死,从这返回之后,就会从这再开始。      return START_STICKY;  }  @Override  public IBinder onBind(Intent intent) {      // 不绑定,返回为null      return null;  }  @Override  public void onDestroy() {    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();   }}

一旦Service在运行,可以通过发送Toast 或是状态栏通知告诉用户

远程通信(IPC) : IPC通常是指跨越两个不同进程之间的通信。如果要用service来实现远程通信,可以用Messenger给service提供一个接口。这样远程之间的通信就可以不用AIDL来实现了。

AIDL(Android Interface Definition Language ):在Android中,一个进程不能正常的访问另外一个进程的内存,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且引领对象通过进程边界。编写以上的代码是非常枯燥乏味的,所以Android提供了一套AIDL机制来处理。当仅仅是你允许来自不同的app的客户端实现IPC并希望在service中处理多线程时可以使用AIDL。如果你不需要从不同的app实现并发的IPC ,你应该通过实现Binder 来创建接口。或是你希望实现IPC,但是没有必要处理多线程,可以用Messenger来实现接口。

public class MessengerService extends Service {    static final int MSG_SAY_HELLO = 1;//处理从客户端发来消息的Handler     class IncomingHandler extends Handler {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case MSG_SAY_HELLO:                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();                    break;                default:                    super.handleMessage(msg);            }        }    }    //发送消息给IncomingHandler()    final Messenger mMessenger = new Messenger(new IncomingHandler());//当绑定了服务,返回接口给messenger,让messenger传递消息给service    @Override    public IBinder onBind(Intent intent) {        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();        return mMessenger.getBinder();    }}

仅仅只有activities, services, and content providers 可以绑定service,不能从broadcast receiver绑定service

4.Fragment与Activity的交互:
(1)从Activity传递参数到Fragment

FragmentTransaction tran = getSupportFragmentManager().beginTransaction();ItemListFragment leftFrag = new ItemListFragment();Bundle bundle = new Bundle();bundle.putString("data", "activity --> fragment");leftFrag.setArguments(bundle); // Activity传递参数到Fragment

(2)从Fragment传递到Activity:

((MyFragmentActivity)getActivity()).setTitle("Fragment --> Activity data: " + position);

5.Fragment与Fragment的通信:

第一种方式: 先获取到Fragment对象,再调用其方法

// 传递数据给其他Fragment对象public void transferData(MenuBean data) {   ItemDetailFragment f = (ItemDetailFragment)getActivity()         .getSupportFragmentManager().findFragmentById(R.id.item_detail_container);   f.setData(data);}

第二种方式:

能过第三方框架,事件通知机制框架EventBus.这个不仅仅能用于fragment,还可以用于android其他组件之间。

0 0