以前在eclipse上开发Android项目习惯了,突然转到Android studio上总是会有这样那样的不适应。例如使用aidl实现远程服务,也就是RPC机制,在Android studio上的开发与在eclipse上的开发便有诸多不同。如果将服务与客户端放在一个项目中还好处理,不同项目中却是增加不少难度。尤其是Android5.0以后服务禁止隐式启动,很多人就非常不习惯。此处就简单介绍一下在Android studio上的aidl创建远程服务的例子(包括Android4.4和Android5.1的开发)。
工具/原料
- Android studio
方法/步骤
-
新建项目aidl,在aidl中创建aidl文件IMyService.aidl,具体创建过程可以参考http://jingyan.baidu.com/article/6f2f55a15d53c9b5b93e6ca1.html。在aidl文件中声明方法int add(int value1, int value2);具体代码如下:
// IMyService.aidlpackage com.example.aidl;// Declare any non-default types here with import statementsinterface IMyService { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ // 为AIDL服务的接口方法,调用AIDL服务的程序需要调用该方法 int add(int value1, int value2);}
-
编译后会自动生成一个对应的Java文件ImyService,至于这个aidl文件在哪儿呢?就像很多人在Android studio中找不到R文件,他们可以这样查找:点击左上角Packages,找到项目名点开即可。
步骤阅读
-
创建MyService类,提供服务。服务中的onBind方法要返回实现了IMyService方法的一个类,例如此处使用类MyServiceImpl实现aidl接口中的add方法。代码如下:
class MyServiceImpl extends IMyService.Stub{ @Override public int add(int value1, int value2) throws RemoteException { return value1 +value2; }}
整个服务的代码是:
package com.example.aidl;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.support.annotation.Nullable;/** * Created by Administrator on 2015/8/12. */public class MyService extends Service {// @Nullable //实现接口中的方法 class MyServiceImpl extends IMyService.Stub{ @Override public int add(int value1, int value2) throws RemoteException { return value1 +value2; }} //返回方法实现类 @Override public IBinder onBind(Intent intent) { return new MyServiceImpl(); }}
-
然后在Activity中启动该服务就行。注意,Android5.0以后服务不能隐式启动,必须显示启动,不然会报错。
package com.example.aidl;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(); intent.setAction("com.android.MYSERVICE"); //Android5.0后service不能采用隐式启动,故此处加上包名 intent.setPackage("com.example.aidl");// Intent intent = new Intent("com.android.MYSERVICE"); startService(intent); Log.e("MainActivity", "server start"); }}
-
最后,在Manifest中声明该服务:
<service android:name=".MyService"> <intent-filter> <action android:name="com.android.MYSERVICE"></action> <category android:name="android.intent.category.DEFAULT"></category> </intent-filter></service>
-
运行该项目,就可以看到控制台打印了server start,至此,服务端就算ok了。
-
新建项目aidlclient作为客户端,创建一个aidl文件并复制服务端aidl文件的内容(或者直接将服务端aidl文件拷过来),注意包名要一致。在布局文件中设置了一个textview和两个button。首先实现服务的连接和断开:
IMyService iMyService;//实现服务连接private ServiceConnection mConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("MainActivity","connect service start"); iMyService = IMyService.Stub.asInterface(service); Log.e("MainActivity","connect service"); } @Override public void onServiceDisconnected(ComponentName name) { Log.e("MainActivity","disconnect service"); iMyService = null; }};
然后点击button1连接服务:
Intent intent = new Intent();intent.setAction("com.android.MYSERVICE");//Android5.0后service不能采用隐式启动,故此处加上包名//此处包名与aidl文件包名一致intent.setPackage("com.example.aidl");bindService(intent, mConn, Context.BIND_AUTO_CREATE);
最后调用服务的方法即可:
try { i = iMyService.add(2, 3);} catch (RemoteException e) { e.printStackTrace();}
具体代码如下:
package com.example.aidlclient;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.TextView;import com.example.aidl.IMyService;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(com.example.aidlclient.R.layout.activity_main); final TextView textView = (TextView)findViewById(R.id.text); Button button1 = (Button)findViewById(R.id.button1); Button button2 = (Button)findViewById(R.id.button2); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {// Intent intent = new Intent("com.android.MYSERVICE"); Intent intent = new Intent(); intent.setAction("com.android.MYSERVICE"); //Android5.0后service不能采用隐式启动,故此处加上包名 //此处包名与aidl文件包名一致 intent.setPackage("com.example.aidl"); bindService(intent, mConn, Context.BIND_AUTO_CREATE); } }); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int i = 0; try { i = iMyService.add(2, 3); } catch (RemoteException e) { e.printStackTrace(); }// textView.setText(i); Log.e("MainActivity",i +">>>>>>>>>>"); } }); } IMyService iMyService; //实现服务连接 private ServiceConnection mConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("MainActivity","connect service start"); iMyService = IMyService.Stub.asInterface(service); Log.e("MainActivity","connect service"); } @Override public void onServiceDisconnected(ComponentName name) { Log.e("MainActivity","disconnect service"); iMyService = null; } };}
-
顺便贴出客户端布局文件:
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity"> <TextView android:id="@+id/text" android:text="@string/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/button1" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="connection"/> <Button android:id="@+id/button2" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="get"/></LinearLayout>
-
最后贴出服务端和客户端的结构图:
步骤阅读
步骤阅读
END
本文来自投稿,不代表幸运快三立场,转载请注明出处:http://www.morucat.com/digital/9747.html