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

来源:互联网 发布:超图软件股票最新消息 编辑:程序博客网 时间:2024/06/07 11:47

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 statementsinterface 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设为空,这样我们就可以实现数据的同步。    这里可能设计安全问题,由于我的能力尚且不足,还请各位多指正。
0 0
原创粉丝点击