Service跨进程调用服务三部曲之AIDL详解(三)

RemoteCallbackList的使用:


使用android中的AIDL让Service与Activity通信(service回调activity)

在很多情况下是需要远程服务端主动给客户端返回数据,客户端只需要进行监听即可,这是典型的观察者模式。这篇文章主要来解决一下这个问题。


因为是跨进程的通信协议,需要创建两个项目,一个项目是后台程序,一个是启动该后台服务的客户端,通过启动这两个项目来演示2个进程间的通信。

步骤1创建Service项目,将该项目中的Activity类删除,把AndroidManifest.xml中的activity配置删除。

步骤2:创建一个file,命名为ICallback.aidl, 作为Activity中的回调方法

Java代码:

package com.example.aidl3;
interface ICallback{
void showResult(int result);
}

再创建一个AIDL接口文件,命名为IService.aidl

Java代码:

package com.example.aidl3;
interface ICallback{
void showResult(int result);
}

步骤3新建包结构com.example.aidlService3,自定义MyService.java类,该类继承Service

Java代码:

package com.example.service3;
import com.example.aidl3.ICallback;
import com.example.aidl3.IService;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;


public class MyService extends Service{


private static final String tag = "MyService";
private int value=0;
private static final int REPORT_MSG = 0;


private RemoteCallbackList<ICallback> myCallback=new RemoteCallbackList<ICallback>();

private IService.Stub mBinder=new IService.Stub() {

@Override
public void unregisterCallback(ICallback cb) throws RemoteException {
// TODO Auto-generated method stub
if(cb!=null){
myCallback.unregister(cb);
}
}

@Override
public void registerCallback(ICallback cb) throws RemoteException {
// TODO Auto-generated method stub
if(cb!=null){
myCallback.register(cb);
}
}
};



@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub

return mBinder;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
mHandler.sendEmptyMessage(REPORT_MSG);
}

@Override
     public void onDestroy() {
         mHandler.removeMessages(REPORT_MSG);
         myCallback.kill();
         super.onDestroy();
     }


     private void callBack() {
         int N = myCallback.beginBroadcast();
         int mValue=++value;
         try {
            for (int i = 0; i < N; i++) {
          myCallback.getBroadcastItem(i).showResult(mValue);
           }
            mHandler.sendEmptyMessageDelayed(REPORT_MSG, 1*1000);
          
       //    Toast.makeText(getApplicationContext(), "showResult()"+mValue, Toast.LENGTH_SHORT).show();
         } catch (RemoteException e) {
            e.printStackTrace();
         }
         myCallback.finishBroadcast();
     }


     private Handler mHandler = new Handler() {


         @Override
         public void handleMessage(Message msg) {
             callBack();
             super.handleMessage(msg);
        }
     };
}

步骤4:

AndroidManifet.xml 中注册 Service

 <service android:name="com.example.service3.MyService"
             android:process=":remote"
            android:exported="true">
            <intent-filter >
                <action android:name="com.service3"/>
            </intent-filter>
        </service>
    </application>

服务端的结构如下:



步骤5:创建客户端,Service项目中创建的ICallBack.aidl和IService.aidl接口连包一起复制到Client项目中

客户端的结构如下:


Java代码:

package com.example.client_aidl3_activity;

import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.aidl3.ICallback;
import com.example.aidl3.IService;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;

public class MainActivity extends Activity implements OnClickListener{

private IService mService;
private TextView tv;
private Button btBinder;
private String mResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
btBinder=(Button) findViewById(R.id.bt_binder);
btBinder.setOnClickListener(this);

}

/**
     * service的回调方法
     */
private ICallback.Stub mCallBack= new ICallback.Stub() {

@Override
public void showResult(int result) throws RemoteException {
// TODO Auto-generated method stub
Log.i("test", "showResult:"+result);
mResult=result+"";
// Message message=new Message();
//Message message=Message.obtain()避免分配新的对象,减少内存的开销
Message message=Message.obtain();
message.what=0;
handler.sendMessage(message);

}
};

private  Handler handler=new Handler(){


@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
tv.setText("result"+mResult);
break;


default:
break;
}
}

};

@Override
     protected void onDestroy() {
         if(mService!=null){
            try {
                mService.unregisterCallback(mCallBack);
             } catch (RemoteException e) {
                 Log.e("TAG", "", e);
             }
         }
         //destroy的时候不要忘记unbindService
          unbindService(conn);
         super.onDestroy();
     }

private ServiceConnection conn= new ServiceConnection() {

@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
mService=null;
tv.setText("unconnect");
}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
mService=IService.Stub.asInterface(service);
try {
mService.registerCallback(mCallBack);
tv.setText("connect");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bt_binder:
Intent intent=new Intent();
intent.setAction("com.service3");
intent.setPackage("com.example.aidl3");
bindService(intent, conn, BIND_AUTO_CREATE);
Toast.makeText(this, "server 已连接", Toast.LENGTH_SHORT).show();
break;

}
}

}


客户端activity_main.xml的代码如下

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.client_aidl3_activity.MainActivity" >


    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
       
       />
<Button 
   android:id="@+id/bt_binder"
   android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv"
          android:layout_centerInParent="true"
           android:text="binder"/>

</RelativeLayout>

这是本人这一个星期实习所学所写的关于Service跨进程调用服务的AIDL使用的总结的第三个,没有学过AIDL的朋友可以先查看前面两个例子。

Service跨进程调用服务三部曲之AIDL详解(一):http://blog.csdn.net/yzwty/article/details/51924121

Service跨进程调用服务三部曲之AIDL详解(二):http://blog.csdn.net/yzwty/article/details/51924364



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值