以前写了一篇文章是关于同一个应用中有一个Activity 和 一个 Service,然后在AndroidManifest.xml文件中 将service的  android:process设置为":remote" , 这里要强调一下带“:”和不带“:”时的属性, android:process=":remote",代表在应用  程序里,当需要该service时,会自动创建新的进程,意思就是说你配的service会在另外一个进程中运行,而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。上次虽然同一个应用中实现了Activity和Service的夸进程通信,但是感觉不爽,毕竟是在同一应用中,这次实现一个两个应用中的跨进程使用aidl通信。1 首先在创建一个应用工程MyApplication4,作用就是创建一个继承自Service的一个服务类,然后再创建一个aidl 文件。Myservice.java
package com.example.lsw.myapplication;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;public class MyService extends Service {    public MyService() {    }    @Override    public IBinder onBind(Intent intent) {        Log.d(MainActivity.TAG,"onBind");        // TODO: Return the communication channel to the service.       return new MyBinder();    }    @Override    public void onCreate() {        Log.d(MainActivity.TAG,"onCreate");        super.onCreate();    }    @Override    public boolean onUnbind(Intent intent) {        return super.onUnbind(intent);    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.d(MainActivity.TAG,"onStartCommand");        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        Log.d(MainActivity.TAG,"onDestroy");        super.onDestroy();    }    public class MyBinder extends IMyAidlInterface.Stub{        @Override        public String getMusicName() throws RemoteException {            return "明天会更好";        }    }}

这里也强调一个知识点,启动Service一共有两种方法,一个是StartService,这种启动方式一般启动的Service和当前启动它的组件就没有任何关系了,和这个组件处于不同的进程了。 另一种启动方式就是bindService这种方法,这种启动方式Service和绑定它的组件共存亡。(具体情况大家可以去查看service的启动方式)。

IMyAidlInterface.aidl

// IMyAidlInterface.aidlpackage com.example.lsw.myapplication;// Declare any non-default types here with import statementsinterface IMyAidlInterface {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     */    String getMusicName();}

这里就是定义一个接口,在MyService中定义一个class 去继承这个接口然后,实现这个接口的方法,之后再通过onBind()方法将这个继承接口类的对象返回给绑定的应用中,实现可以访问到MyService内部方法的机制。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>                                                                                                

这里强调一下属性 android:exported="true"表示这个进程中的MyService服务允许外接访问。

可以看到这了的aidl包名为 com/example/lsw/myapplication

2 Client 端
(1) 重新创建一个应用工程MyApplication5,主要任务就是在Mainactivity.java中点击button1去绑定MyApplication4中的MyService,然后点击button2调用 aidl中的getMusicName()方法。
Mainctivity.java

package com.example.lisiwei.myapplication;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.Toast;import com.example.lsw.myapplication.IMyAidlInterface;public class MainActivity extends AppCompatActivity {    private Button m_startButton = null;    private Button m_getMusicButton = null;    private ServiceConnection m_serviceConnection = null;    private IMyAidlInterface m_iMyAidlInterface = null;    private Context m_context = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init() {        m_context = this;        m_startButton = findViewById(R.id.startButton);        m_getMusicButton = findViewById(R.id.getMusicButton);        m_serviceConnection = new ServiceConnection() {            @Override            public void onServiceConnected(ComponentName name, IBinder service) {                Log.d("lisiwei","onServiceConnected");                if (null == m_iMyAidlInterface) {                    m_iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);                }            }            @Override            public void onServiceDisconnected(ComponentName name) {            }        };        m_startButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.d("lisiwei","m_startButton setOnClickListener");                Intent intent = new Intent();                // 这里注意这两个参数第一个是Myservice的包名也就是application4的包名,第二个是包名+类型,                intent.setComponent(new ComponentName("com.example.lsw.myapplication","com.example.lsw.myapplication.MyService"));                bindService(intent,m_serviceConnection,Context.BIND_AUTO_CREATE);            }        });        m_getMusicButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.d("lisiwei","m_getMusicButton setOnClickListener + " + getMusicName());                Toast.makeText(m_context,getMusicName(),Toast.LENGTH_LONG).show();            }        });    }    private String getMusicName() {        String name = null;        if ( null != m_iMyAidlInterface) {            try {                name = m_iMyAidlInterface.getMusicName();            } catch (RemoteException e) {                e.printStackTrace();            }        }        return name;    }}

这里需要强调4个点:
1 因为我们需要去绑定application4中的service就涉及到了Intent启动service,自从Android 5.0之后就不允许隐式启动intent 启动service了,只能显示intent启动service。
2 就是比较坑的一个地方,这里感谢同事的指导,就是要将application4中的aidl文件copy到application5中,而且两个应用中的aidl要处于同一个目录下。
3 这个又是一个坑逼的地方,我要通过application5(client)去绑定application4中service,结果必须要先启动application4的工程,注意这里只是启动了工程,并没有启动application4中的service,service还是由application5中点击button来绑定。你可以看log,是点击button之后application4中的service还是第一次走onCreate方法,那就证明application4只是启动了它自身的工程,并没有启动服务,服务还是由application5绑定之后启动的。
4 为什么不在application5中启动Myservice的时候又通过m_iMyAidlInterface去调用getMusicName()方法那?因为绑定是一个异步执行的过程,如果绑定之后立马去使用m_iMyAidlInterface这个时候m_iMyAidlInterface还可能是null。

这里这个项目的路径名和application4不一样,但是aidl的路径名一样 都为com/example/lsw/myapplication

具体代码路径: https://download.csdn.net/download/lisiwei1994/10946447

更多相关文章

  1. android 使用AsyncTask实现异步下载文件
  2. android通过更改hosts免优酷广告方法
  3. 如何优雅的避免android(安卓)运行时崩溃
  4. android 热修复之类加载机制
  5. Android进阶(一)View体系
  6. [android] HttpURLConnection的初步学习
  7. 深入了解Android(安卓)任务和进程
  8. Android(安卓)应用初始化及窗体事件的分发
  9. Android(安卓)三言两语

随机推荐

  1. Android(安卓)开发一定要看的15个实战项
  2. Android(安卓)安全攻防(一):SEAndroid的编译
  3. Android文件操作中的openFileOutPut和ope
  4. 浅谈android的selector,背景选择器
  5. Android入门 — 模拟器的创建和运行
  6. [Android]仿Windows Phone的启动器,无广告
  7. Android消息推送实现
  8. Android的消息机制(Handler的工作原理)
  9. android TextView属性大全(转)
  10. android设备连接到pc进行应用程序调试