Service-IntentService&Service-AIDL进程间通信

什么是Service-IntentService?

IntentService 是继承自 Service 并处理异步请求的一个类,在 IntentService内有一个工作线程来处理耗时操作,当任务执行完后,IntentService 会自动停止,不需要我们去手动结束,可以看做是Service和HandlerThread的结合体,在完成了使命之后会自动停止,适合需要在工作线程处理UI无关任务的场景,如果启动 IntentService 多次,那么每一个耗时操作会以工作队列的方式在 IntentService 的 onHandleIntent 回调方法中执行,依次去执行,使用串行的方式,执行完自动结束。

优与劣

优势:不需要开启线程
劣势:使用广播向activity传值

案例演示

使用IntentService网络请求json串,将json串使用广播发送给activity界面:

步骤:创建服务、注册服务、启动服务

MainActivity:

public class MainActivity extends AppCompatActivity {
    private  MyReceiver myReceiver;
    private Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //注册广播
        IntentFilter intentFilter=new IntentFilter();
        intentFilter.addAction("com.bawei.intentservice");
        myReceiver=new MyReceiver();
        registerReceiver(myReceiver,intentFilter);
        //开启服务
        intent=new Intent(this,MyIntentService.class);
        startService(intent);


    }
    //解除广播+关闭服务
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(myReceiver);
        stopService(intent);
    }

    class MyReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            String action=intent.getAction();
            if("com.bawei.intentservice".equals(action)){
                Bundle bundle = intent.getExtras();
                String json = bundle.getString("json", "");
                //接续json串 展现在ListView 中
                Toast.makeText(context, ""+json, Toast.LENGTH_SHORT).show();

            }
        }
    }
}

Service:

public class MyIntentService extends IntentService {
    //TODO  注意:必须提供无参数构造,不然清单文件中注册报错
    public MyIntentService(){
        super("MyIntentService");
    }

    public MyIntentService(String name) {
        super(name);
    }
    //TODO  将所有耗时操作都在该方法中完成,相当于开启线程
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        StringBuffer sb=new StringBuffer();
        HttpURLConnection connection=null;
        InputStream inputStream=null;
        try {
            URL url=new URL("http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=20&page=1");
            connection = (HttpURLConnection) url.openConnection();
            connection.setReadTimeout(5*1000);
            connection.setConnectTimeout(5*1000);

            if(connection.getResponseCode()==200){
                inputStream  = connection.getInputStream();
                byte[] b=new byte[1024];
                int len=0;
                while((len=inputStream.read(b))!=-1){
                    sb.append(new String(b,0,len));
                }
                //TODO 向Activity或Fragment发送json串
                Intent intent1=new Intent();
                intent1.setAction("com.bawei.intentservice");
                Bundle bundle = new Bundle();
                bundle.putString("json",sb.toString());
                intent1.putExtras(bundle);
                sendBroadcast(intent1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(inputStream!=null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                connection.disconnect();
            }
        }
    }
}

什么是Service-AIDL?

AIDL,全称是Android Interface Define Language,即安卓接口定义语言,可以实现安卓设备中进程之间的通信(Inter Process Communication, IPC)
安卓中的服务分为两类:
本地服务(例如:网络下载大文件,音乐播放器,后台初始化数据库的操作)
远程服务(例如:远程调用支付宝进程的服务)

使用步骤

服务端:

创建AIDL文件
修改aidl文件,提供一个方法,该方法 就是处理客户端的请求
rebuild project之后会发现自动生成一个Java文件:IMyAidlInterface.java
在服务端中新建一个类,继承Service,在其中定义一个IBinder类型的变量iBinder,引用上述接口IMyAidlInterface.java类中的Stub类对象,实现其中的add方法,在Service的onBind方法中,返回iBinder变量
清单文件中注册SErverService服务,在注册时应设置exported属性为true,保证该Service能被其他应用调用,否则会报java.lang.SecurityException: Not allowed to bind to service Intent 异常

客户端:

在客户端创建同样AIDL文件,要求包名AIDL名字必须一致,内容也必须一样提供add方法,rebuild 项目
绑定服务调用服务器进程的方法

先启动服务端,再启动客户端

public class ServerService extends Service {
    //TODO 代理人
    IBinder binder=new IMyAidlInterface.Stub() {
        @Override
        public int add(int num1, int num2) throws RemoteException {
            return num1+num2;
        }
    };
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
}
public class MainActivity extends AppCompatActivity {
    IMyAidlInterface iMyAidlInterface;
    //3.绑定服务回调
    private ServiceConnection connection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //绑定服务成功后,返回服务端返回的binder,将其转成IMyAidlInterface调用add方法
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
            try {
                int num=iMyAidlInterface.add(4,6);//调用服务端的add方法并得到结果
                Toast.makeText(MainActivity.this, ""+num, Toast.LENGTH_SHORT).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            //解除绑定时调用, 清空接口,防止内容溢出
            iMyAidlInterface=null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1.绑定服务
        Intent intent=new Intent();
        intent.setAction("com.bawei.1609A");//设置action
        intent.setPackage("com.example.aidl_server");//设置服务端应用进程包名
        bindService(intent,connection, Service.BIND_AUTO_CREATE);
    }
    //2.解除绑定
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值