Android专题8——本地服务和远程服务通信

关于远程服务

  • 远程服务指的是服务和访问者不在同一个应用程序中,即不在同一个进程中。

  • 访问远程服务类似进程间通信。

  • 访问者和远程服务需要遵守能够被操作系统理解的协议,AIDL。

1. 在服务端和客户端配置AIDL

  • aidl文件最好都放在aidl目录下,aidl文件用于接口描述

  • 会自动生成一个同名的JAVA文件

  • 在自动生成的JAVA文件中,系统会自动定义一个Stub类,继承Binder类,实现aidl文件中描述的接口

 

2. 编写service业务代码

  • 在清单文件中注册

  • 实现自定义的IBinder

        <service android:name=".StudentService">
            <intent-filter >
                <action android:name="com.njulya.REMOTESERVICE"/>
            </intent-filter>
        </service>
View Code
import com.njulya.aidl.StudentQuery;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class StudentService extends Service {
    IBinder iBinder;
    String[] names = {"张阳","李永安","潘杰"};
    @Override
    public IBinder onBind(Intent intent) {
        iBinder = new StudentBinder();
        return iBinder;
    }
/**
 * 实现IBinder接口,用于通信
 * @author Andy
 */
    private class StudentBinder extends StudentQuery.Stub{
        @Override
        //aidl文件中描述的接口
        public String query(int no) throws RemoteException {
            return names[no-1];//业务代码
        }
        
    }
}
View Code

 

 

3.编写客户端应用

package com.njulya.remoteserviceclient;

import com.njulya.aidl.StudentQuery;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
    
    private EditText studentId;
    private TextView content;
    private StudentQuery studentQuery;
    private ServiceConnection conn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        studentId = (EditText)this.findViewById(R.id.student_id);
        content = (TextView)this.findViewById(R.id.content);
        conn = new StudentConnetion();
        Intent service = new Intent("com.njulya.REMOTESERVICE");
        this.bindService(service, conn, BIND_AUTO_CREATE);
    }
    /**
     * 按键触发业务代码
     * @param v
     */
    public void queryOnClick(View v){
        int no = Integer.valueOf(studentId.getText().toString());
        try {
            String studentName = studentQuery.query(no);
            content.setText(studentName);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    private class StudentConnetion implements ServiceConnection{
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //将IBinder代理对象转换为接口类型
            studentQuery = StudentQuery.Stub.asInterface(service);
        }
        
        @Override
        public void onServiceDisconnected(ComponentName name) {
            studentQuery = null;
        }
    }
    
    
    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    


}
View Code

 

关于本地服务

  • 启动的service是运行在主线程中的,所以耗时的操作还是要新建工作线程

  • 用bindService时需要实现ServiceConnection,flags用BIND_AUTO_CREATE

  • service中关键要返回IBinder的实现类对象,该对象中会使用服务中的一些API

  • 一般在自定义的ServiceConnection实现类中得到和关闭IBinder对象

  • 通过得到的IBinder对象实现调用服务中的API

业务界面

客户端代码

package com.njulya.intsum;

import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

    private EditText num1;
    private EditText num2;
    private TextView sum;
    private ServiceConnection conn;
    
    //自定义的公共接口,用于求两数之和
    private SumOfTwo sumOfTwo;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        num1 = (EditText)this.findViewById(R.id.num1);
        num2 = (EditText)this.findViewById(R.id.num2);
        sum = (TextView)this.findViewById(R.id.sum);
        Button button = (Button)this.findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                sum();
            }
        });
        conn = new SumConnetion();
        Intent service = new Intent(this, SumService.class);
        this.bindService(service, conn, BIND_AUTO_CREATE);
    }

    protected void sum() {
        int number1 = Integer.valueOf(num1.getText().toString());
        int number2 = Integer.valueOf(num2.getText().toString());
        int result = sumOfTwo.sum(number1, number2);
        sum.setText(String.valueOf(result));
        
    }
    private class SumConnetion implements ServiceConnection{
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            sumOfTwo = (SumOfTwo)service;
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            sumOfTwo = null;
        }
    }
    
    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}
View Code

服务端代码

package com.njulya.intsum;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class SumService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return new SumBinder();
    }
    public class SumBinder extends Binder implements SumOfTwo{
        @Override
        public int sum(int number1, int number2) {
            return number1 + number2;
        }
        
    }
}
View Code

 

转载于:https://www.cnblogs.com/lya-nju/p/4236501.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值