Android不同应用间的活动和服务的数据同步

在android的学习过程中,我理解了在同个应用中的活动和服务之间的数据同步;于是我想,不同应用中的活动和服务是否也可以同步数据呢,这里给出了我的一种方法,仅供参阅。
 服务与活动之间的数据同步,在同一个应用中,可以通过定义回调接口来保持数据同步更新,但是在不同的应用中,活动无法获得另一个应用中服务的回调接口,这样的方法就不可行了。但是在活动和服务之间的连接是肯定可以建立的,通过设置这样的intent就行
`intent=new Intent();
intent.setComponent(new ComponentName("服务的包名","服务的包名.服务类名"));`
 这时,我们通过启动和绑定服务就可以在活动和服务之间建立连接,我们都知道建立的连接得有一个binder,平常都是通过重写onBind函数的返回值来返回binder,然后通过活动中的onServiceConnected函数来获得binder。但是不同应用中获取binder的方法略有不同,我们需要返回的值不是自己定义的Binder类的一个变量,而是实现了AIDL接口的值,并且两个应用都需要定义同样的aidl文件。在aidl文件中,我们新声明了一个函数String getData(),用来返回服务中的数据,然后通过binder来存储这个值,传递到活动中去。
 AIDL文件的代码,在原有aidl的基础上声明了一个函数:
// Declare any non-default types here with import statements

interface IAppSyncInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
    String getData();
}
下面是服务的代码,服务所在的应用名称叫做app
/*app中的服务,我们需要使用这个服务来建立与another这个应用的通信;
* 在onCreate中创建一个线程,这个线程里存在一个不断变化的数字
* 我们需要将这个变化的数字同步与之进行通信的另一个应用中,这个应用的名称叫做app
* 我们通过AIDL接口来声明完成传递数据任务的函数getData,将不断变化的全局变量data传递出去*/
public class MyService extends Service {
    private String data="默认数据";//服务中的数据
    private int i=0;//服务中不断变化的数字
    private boolean running=false ;//线程中while循环的执行条件,只要服务在运行,线程就不会停止
    public MyService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        return new IAppSyncInterface.Stub() {//在这里重定义onBind的返回值,与activity进行绑定
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
            }
            public String getData(){//这个函数将服务中的数据传递出去,这个函数需要在AIDL接口(两个AIDL)中声明
                return MyService.this.data;
            }
        };
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","started");
        running =true;
        new Thread(){
            @Override
            public void run() {
                super.run();
                while(running){
                    i++;
                    data=i+"";
                    System.out.println(data);
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        running=false;
        Log.d("MyService","stoped");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
}
在这个服务中,我们定义了一个String data,用作这个服务中的数据,在onCreaet函数中,我们设置了一个线程,在这个线程中,我们让一个整型变量i不断增加,用于代替服务中不断变化的data。在onBind函数的返回值里,我们定义了接口中的函数getData,这样我们可以通过服务中的binder来获取服务中的data了,但是现在还不能实现数据的同步,因为没有回调函数来实现同步,接下来给出活动的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener,ServiceConnection{
    private Intent intent;
    private TextView textView;
    private Bundle b;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView=(TextView)findViewById(R.id.textview);
        findViewById(R.id.startService).setOnClickListener(this);
        findViewById(R.id.stopService).setOnClickListener(this);
        findViewById(R.id.bindService).setOnClickListener(this);
        findViewById(R.id.unbindService).setOnClickListener(this);
        intent=new Intent();
        intent.setComponent(new ComponentName("com.example.test_startservicefromanotherapp","com.example.test_startservicefromanotherapp.MyService"));
        //通过设置包名和类名来指定服务,启动服务和绑定服务都使用这个intent
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.startService:
                startService(intent);
                break;
            case R.id.stopService:
                stopService(intent);
                break;
            case R.id.bindService:
                bindService(intent,this, Context.BIND_AUTO_CREATE);
                break;
            case R.id.unbindService:
                unbindService(this);
                binder=null;
                break;
        }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //当bindService执行后,就会执行这个函数
        Log.d("Myservice","绑定成功");
        binder=IAppSyncInterface.Stub.asInterface(service);
        //获取Service,转化为binder,全局变量binder这时已经代表了活动和服务之间的联系
        new Thread(){
            @Override
            public void run() {
                super.run();
                while(binder!=null){
                    Message msg=new Message();
                    b=new Bundle();
                    try {
                        sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    try {
                        if(binder!=null) {
                            b.putString("data", binder.getData());
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    msg.setData(b);
                    handler.sendMessage(msg);
                    //将消息的获取和传递都放入这个线程中,不断的重新getData
                    //将binder所载的值传递进来
                }
            }
        }.start();

    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        System.out.println("死循环被关闭");
    }
    private IAppSyncInterface binder=null;
    private Handler handler=new Handler(){
        //将msg中的数据放入textView,实现两个进程间的通信
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            textView.setText(msg.getData().getString("data"));
        }
    };
}
我们可以看到,在活动中,我们重写了onServiceConnected函数,将一个新的线程放入其中,刷新的频率相对较高,且循环执行的条件是binder不为空,并且在binder为空的时候也不能执行getData方法,防止了空对象的出现,在unbindService函数执行之后还将binder设为空,这样我们就可以实现数据的同步。
    这里可能设计安全问题,由于我的能力尚且不足,还请各位多指正。