您的位置:首页 > 移动开发 > Android开发

Android学习之远程绑定调用service(文章有误,请勿阅读)

2013-01-08 00:01 417 查看
特别说明:

文章有误,请后来的人不要被我误导了,后面会重新出篇新文章替换这个有错误的文章!!

感谢下面的人指出错误,初学android理解有误。


</pre><p></p><p></p><pre name="code" class="java">最近今天在学习service控件,前面的后台service和绑定本地控件的service的很容易理解,几乎没遇到什么问题,但看到远程调用service的时候模仿书上的例题,结果发现竟然得不到想要的结果,把书上的例子源码弄进去,还是会有问题,于是经过好几天的自己摸索和网上参考一些资料,主要得到帮助的来自http://www.cnblogs.com/TerryBlog/archive/2010/08/24/1807605.html         http://ericchan2012.iteye.com/blog/1554197 这2个网址。接下来直接进入正题,对这几天对远程绑定调用service的学习结果。


远程绑定调用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();
}

});

}
}


IAidlService.aidl

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 id=" + startId);
}
*/
@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="http://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="http://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,由于没有按钮不能多次按,也就会造成得不到想要的结果了。这里总算明白它的一些运行机制了,先写到这里,后面有什么新发现会及时更新。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐