Android 多进程通讯之 AIDL
2016-07-19 18:38
543 查看
下午闲来无事,学习了下Android应用层开发的多进程通讯方式之AIDL。
AIDL是Android Interface Definition Language(安卓接口定义语言)。android应用的多进程通讯的一实现方式,当然,你也可以通过发送广播的方式等等。
这里,只是来介绍AIDL的使用方式。
这个demo主要是来实现,主进程操作service,实现音乐的播放和停止。
1. 首先,新建一个aidl文件,IRemoteService.aidl.
aidl文件,在编译的时候,apt会产生相应的java文件。且里面的接口不能使用public关键字。
2. 创建服务进程代码逻辑。
新建类:PlayerService(com.player.playerserver.PlayerService),继承Service。
这里贴出其代码:
3. 在AndroidManifest.xml文件对Service声明。
4. 在我们的Activity中,进行与此Service进行通讯。
这里贴一下,布局文件:
这样,我们可以通过这种方式,可以跟第三方的sdk或者apk通讯了。这样可以增加自己APP的稳定性
AIDL是Android Interface Definition Language(安卓接口定义语言)。android应用的多进程通讯的一实现方式,当然,你也可以通过发送广播的方式等等。
这里,只是来介绍AIDL的使用方式。
这个demo主要是来实现,主进程操作service,实现音乐的播放和停止。
1. 首先,新建一个aidl文件,IRemoteService.aidl.
package com.playerserver; // Declare any non-default types here with import statements interface IRemoteService { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); //vnbo add void play(); void stop(); //vnbo end }这个文件,主要是用来主进程和服务进程通讯接口。
aidl文件,在编译的时候,apt会产生相应的java文件。且里面的接口不能使用public关键字。
2. 创建服务进程代码逻辑。
新建类:PlayerService(com.player.playerserver.PlayerService),继承Service。
这里贴出其代码:
package com.player.playerserver; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import com.playerserver.IRemoteService; import com.player.R; import java.io.FileDescriptor; public class PlayerService extends Service { private MediaPlayer mPlayer; public PlayerService() { } //Service的接口 @Override public IBinder onBind(Intent intent) { Log.e("vnbo","vnbo PlayerService onBind"); if(mPlayer == null){ mPlayer = new MediaPlayer(); try{ FileDescriptor fd = getResources().openRawResourceFd(R.raw.test).getFileDescriptor(); // 获取音乐数据源,在raw文件夹下,放一个test.mp3的音乐文件。 mPlayer.setDataSource(fd); // 设置数据源 } catch (Exception e) { e.printStackTrace(); } mPlayer.setLooping(true); } return mBinder; } //使用之前创建的aidl接口。 private IBinder mBinder = new IRemoteService.Stub() { //自定义逻辑接口 @Override public void stop() throws RemoteException { Log.e("vnbo","vnbo PlayerService stop"); try { if (mPlayer.isPlaying()) { mPlayer.stop(); } } catch (Exception e) { e.printStackTrace(); } } //自定义逻辑接口 @Override public void play() throws RemoteException { try { Log.e("vnbo","vnbo PlayerService play"); if (mPlayer.isPlaying()) { return; } mPlayer.prepare(); mPlayer.start(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString){ Log.e("vnbo","vnbo PlayerService basicTypes"); } }; //Service的接口 @Override public boolean onUnbind(Intent intent) { Log.e("vnbo","vnbo PlayerService onUnbind"); if (mPlayer != null) { mPlayer.release(); } return super.onUnbind(intent); } }
3. 在AndroidManifest.xml文件对Service声明。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.player" > <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name="com.player.MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.player.playerserver.PlayerService" android:process=":remote" android:enabled="true" android:exported="true" > <intent-filter> <action android:name="com.player.playerserver.PlayerService" /> </intent-filter> </service> </application> </manifest>
4. 在我们的Activity中,进行与此Service进行通讯。
package com.player; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.Button; import com.playerserver.IRemoteService; public class MainActivity extends AppCompatActivity { public static final String ACTION = "com.player.playerserver.PlayerService"; private Button mPlayBtn, mStopBtn; private IRemoteService mService; private boolean isBinded = false; //主进程与服务进程连接的回调接口 private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Log.e("vnbo","vnbo MainAcitvity onServiceDisconnected"); isBinded = false; mService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("vnbo","vnbo MainAcitvity onServiceConnected"); mService = IRemoteService.Stub.asInterface(service); isBinded = true; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); doBind(); initViews(); } private void initViews() { mPlayBtn = (Button) findViewById(R.id.button_play); mStopBtn = (Button) findViewById(R.id.button_stop); mPlayBtn.setOnClickListener(clickListener); mStopBtn.setOnClickListener(clickListener); } //与服务进程建立联系 public void doBind() { Intent intent = new Intent(ACTION); intent.setPackage(getPackageName());//android5.0之后,intent要显示声明。如果这个service在另一个应用中,则需要setComponent。 bindService(intent, conn, Context.BIND_AUTO_CREATE); } public void doUnbind() { if (isBinded) { unbindService(conn); mService = null; isBinded = false; } } private View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View v) { if (v.getId() == mPlayBtn.getId()) { // play try { mService.play(); //调用播放逻辑接口 } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { // stop try { mService.stop();//调用暂停逻辑接口 } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
这里贴一下,布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/activity_main" tools:context=".MainActivity"> <Button android:id="@+id/button_play" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="play" /> <Button android:id="@+id/button_stop" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/button_play" android:layout_marginTop="20dp" android:text="stop" /> </RelativeLayout>
这样,我们可以通过这种方式,可以跟第三方的sdk或者apk通讯了。这样可以增加自己APP的稳定性
相关文章推荐
- Android所谓滤镜
- Android Volley框架使用(一)
- Android将应用log信息保存文件
- Android开发之用Bmob实现短信验证码功能
- Android JAVA文件遍历小妙招
- Android 的欢迎引导页
- Android RecyclerView使用详解
- Android 动画之ScaleAnimation应用详解
- android中ScrollView常用属性汇总
- 你可能漏掉的知识点: onResumeFragments
- Android ScrollView如何设置maxHeight
- android中的图片处理
- fresco--facebook推出的一款强大的android图片处理库
- Android系统应用间传递消息方法
- 首次接触Android NDK后的感受
- Android学习总结——获取被启动的Activity传回的数据
- Android事件传递机制(dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent)
- android studio 预览问题 :java.lang.NoClassDefFoundError:com/android/util/PropertiesMap
- Android四大组件之ContentProvider使用方法
- 使用开源项目实现ListView下拉刷新