Android 多进程通讯之 AIDL
来源:互联网 发布:java 线程池 编辑:程序博客网 时间:2024/06/01 07:19
下午闲来无事,学习了下Android应用层开发的多进程通讯方式之AIDL。
AIDL是Android Interface Definition Language(安卓接口定义语言)。android应用的多进程通讯的一实现方式,当然,你也可以通过发送广播的方式等等。
这里,只是来介绍AIDL的使用方式。
这个demo主要是来实现,主进程操作service,实现音乐的播放和停止。
1. 首先,新建一个aidl文件,IRemoteService.aidl.
package com.playerserver;// Declare any non-default types here with import statementsinterface 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的稳定性
0 0
- Android 多进程通讯之 AIDL
- Android进程间通讯之AIDL
- Android学习之AIDL进程间通讯
- android开发之进程间通讯aidl
- android aidl 进程间通讯
- android学习之使用AIDL实现进程间的通讯
- Android进程间通讯之重识AIDL
- android 多进程之 AIDL
- 安卓进程通讯之aidl
- Android AIDl来实现进程间通讯
- android aidl进程间的通讯(笔记)
- Android进程间通讯——AIDL
- Android进程间通讯AIDL详解
- Android AIDL实现进程间通讯IPC
- android进程间通讯aidl demo
- Android 多进程通信之AIDL
- 进程间通讯-----aidl
- AIDL进程间通讯
- Android四大组件之ContentProvider使用方法
- (java)处理socket通信过程中粘包的情况
- windows Git Bash 无法运行python文件的解决方法
- Swift3的playground中对UI直接测试支持的改变
- 改变Bitmap的大小
- Android 多进程通讯之 AIDL
- rxjava(二)Single与Subject
- fresco--facebook推出的一款强大的android图片处理库
- slf4j-api、slf4j-log4j12、log4j的关系
- 微服务架构的分布式事务问题
- Linux入门指令
- 【Creator】访问节点或者其他组件
- 老人是真饿了(sort+结构体+贪心) hd 2187
- 面向对象的三大特性,动态绑定,抽象,接口