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的基础上声明了一个函数:
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
public class MyService extends Service {
private String data="默认数据" ;
private int i=0 ;
private boolean running=false ;
public MyService () {
}
@Override
public IBinder onBind (Intent intent) {
return new IAppSyncInterface.Stub() {
@Override
public void basicTypes (int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
public String getData (){
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" ));
}
@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) {
Log.d("Myservice" ,"绑定成功" );
binder=IAppSyncInterface.Stub.asInterface(service);
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);
}
}
}.start();
}
@Override
public void onServiceDisconnected (ComponentName name) {
System.out.println("死循环被关闭" );
}
private IAppSyncInterface binder=null ;
private Handler handler=new Handler(){
@Override
public void handleMessage (Message msg) {
super .handleMessage(msg);
textView.setText(msg.getData().getString("data" ));
}
};
}
我们可以看到,在活动中,我们重写了onServiceConnected函数,将一个新的线程放入其中,刷新的频率相对较高,且循环执行的条件是binder不为空,并且在binder为空的时候也不能执行getData方法,防止了空对象的出现,在unbindService函数执行之后还将binder设为空,这样我们就可以实现数据的同步。
这里可能设计安全问题,由于我的能力尚且不足,还请各位多指正。