Android学习之远程绑定调用service
https://res.3425.com.cn/aliyunqi/v4ezoht0a4y
远程绑定调用service主要是用来不同进程的信息共享。就比如服务器和客户端,在服务器端设置好一个service提供方法或信息,然后客户端可以直接调用服务器端service提供方法或信息。这里有个前提是客户端必须有和服务器端一份一样的AIDL,然后服务器端在客户端使用的系统上有注册过(也就是安装运行过一次),之后客户端就可以远程绑定调用服务器端的service了。
具体的步骤如下:
1.首先,是服务器的
1)创建一个android应用工程
2) 在主Aitivity所在的包里新建个AIDL文件,这是ADT会自动帮你在gen目录下生成一个和AIDL文件同名的JAVA文件(这里的AidlService.java是下一步骤生成的,这里可以先忽略)
3)如上图所示,创建一个用来使用service的类(AidlService.java)
具体每个文件的代码如下:
AidlServerActivity.java
- package com.ds.server;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class AidlServerActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Button bt = (Button) findViewById(R.id.bt);
- bt.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Intent service = new Intent(AidlServerActivity.this,
- AidlService.class);
- startService(service);
- Toast.makeText(AidlServerActivity.this, "service started",
- Toast.LENGTH_LONG).show();
- }
- });
- }
- }
- package com.ds.server;
- interface IAidlService {
- int getType();
- }
AidlService.java
- package com.ds.server;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- public class AidlService extends Service {
- private boolean unrunnable;
- private int count;
- private class MyBinder extends IAidlService.Stub {
- @Override
- public int getType() throws RemoteException {
- // TODO Auto-generated method stub
- return 100;
- }
- }
- private void Log(String str) {
- Log.d("AidlService", "------ " + str + "------");
- }
- @Override
- public void onCreate() {
- super.onCreate();
- /*
- new Thread(new Runnable(){
- @Override
- public void run(){
- while(!unrunnable){
- try{
- Thread.sleep(1000);
- }catch(InterruptedException e){
- }
- count++;
- Log.v("AidlService","count:"+count);
- }
- }
- }).start();
- */
- Log.v("RemoteCountService","onCreate");
- Log("service create");
- }
- /*
- @Override
- public void onStart(Intent intent, int startId) {
- Log("service start border-style:none none none solid;border-left-width:3px;border-left-color:rgb(108,226,108);list-style:outside;color:inherit;line-height:18px;margin:0px;padding:0px 3px 0px 10px;"> }
- */
- @Override
- public IBinder onBind(Intent t) {
- Log("service on bind");
- return new MyBinder();
- }
- @Override
- public void onDestroy() {
- Log("service on destroy");
- unrunnable=true;
- super.onDestroy();
- }
- /*
- @Override
- public boolean onUnbind(Intent intent) {
- Log("service on unbind");
- return super.onUnbind(intent);
- }
- public void onRebind(Intent intent) {
- Log("service on rebind");
- super.onRebind(intent);
- }
- */
- }
布局文件AndroidManifest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="https://schemas.android.com/apk/res/android"
- package="com.ds.server"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="8" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:name=".AidlServerActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <service
- android:name=".AidlService"
- android:enabled="true"
- android:process=":remote" >
- <intent-filter>
- <!-- AIDL完整路径名。必须指明,客户端能够通过AIDL类名查找到它的实现类 -->
- <action android:name="com.ds.server.IAidlService" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </service>
- </application>
- </manifest>
这里,服务器端的工作做好了,接下来是客户端的工作。
2.接着,是客户端的:
1)首先,创建一个工程
2)接着,把服务器端的一些文件拷贝过来(创建com.ds.server这个包,然后往里面复制进入如下图的服务器端的文件(IAidlService.java)
下面是个文件的内容
AidlClientActivity.java
- package com.ds.client;
- import com.ds.server.IAidlService;
- 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.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class AidlClientActivity extends Activity {
- IAidlService iservice;
- int count;
- private ServiceConnection connection = new ServiceConnection() {
- public void onServiceConnected(ComponentName name, IBinder service) {
- // TODO Auto-generated method stub
- // 浠庤繙绋媠ervice涓幏寰桝IDL瀹炰緥鍖栧璞�
- iservice = IAidlService.Stub.asInterface(service);
- Log.i("Client","Bind Success:" + iservice);
- }
- public void onServiceDisconnected(ComponentName name) {
- // TODO Auto-generated method stub
- iservice = null;
- Log.i("Client","onServiceDisconnected");
- }
- };
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final TextView tv = (TextView) findViewById(R.id.tv);
- Button bt = (Button) findViewById(R.id.bt);
- bt.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- // TODO Auto-generated method stub
- Intent service = new Intent(IAidlService.class.getName());
- bindService(service, connection, BIND_AUTO_CREATE);
- if (iservice != null) {
- try {
- Log.v("AidlClientActivity","oncreate"+iservice.getType()+" "+count);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- else{
- count++;
- }
- }
- });
- }
- }
AndroidManifest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="https://schemas.android.com/apk/res/android"
- package="com.ds.client"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="8" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:name=".AidlClientActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
你可能会看到在客户端的Activity文件里,有个count的变量,觉得是多余的,但这是为了说明下面这个问题的需要。
最开始的count是0,然后我运行客户端后,鼠标左击bind按钮,会发现LogCat的verbose窗口会显示
为什么没有执行 Log.v("AidlClientActivity","oncreate"+iservice.getType()+" "+count);这一句,然后我再点击下bind
终于出现想要的结果,这里你就会发现count变成1了,也就是之前执行过一次count+1了,这就说明了,第一次只是绑定,返回的 iservice是null,第二次以上才会返回对象。
到这里就是我之前一直错误的地方,是理解错了,我之前写的程序没有按钮,是直接启动客户端后就绑定调用service,由于没有按钮不能多次按,也就会造成得不到想要的结果了。这里总算明白它的一些运行机制了,先写到这里,后面有什么新发现会及时更新。
最后更新:2017-04-04 07:03:34
上一篇:
看Ubuntu如何提升Linux级别
下一篇:
Win 8狂想 走自己的路让别的系统无路可走?
SQL Update 语句中使用别名
一张图看懂你与AI的优劣势
When does the Oracle library for st_shapelib.dll need to be changed?
Eclipse中编译Android项目工程失败,提示: Error in an XML file: aborting build 解决办法
阿里云启动天池电力AI大赛:用AI解千万企业“用电之痛”
云栖大会新零售峰会7位顶级大咖演讲干货+完整版PPT全分享
mysql批量删除指定前缀的表,批量修改表名的SQL语句
论网站建设的价值体现
Linux下调试段错误的方法[Segmentation Fault]--GDB
Eclipse快捷键大全