一. 前言 1. 什么是进程?
就是运行的一个程序。
每个进程都有独立的代码和数据空间,进程间的切换会有较大的开销,一个进程包含1~n个线程。
进程是资源分配的最小单位。
一个进程一直运行,直到所有的非守护线程都结束运行后才能结束。
2. 什么是多进程? 多进程是指操作系统同时运行多个进程。
3. 进程如何创建?
4. 进程的等级
二. 多进程 1. 什么情况下使用多进程? Android中一个进程的内存是有限的,当需要更多的内存时。
2. 使用多进程需要注意哪些地方? 多个进程可能会导致全局初始化操作多次执行。
1 2 3 4 5 6 7 8 9 10 11 public class MainApplication extends Application { @Override public void onCreate () { super .onCreate(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?xml version="1.0" encoding="utf-8" ?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package ="swu.xl.messenger" > <application android:name=".MainApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
三. 进程间的通信 IPC(inter process communication) 1. 为什么需要进程间的通信 进程间内存的不可见性,导致了内存不共享。
2.如何通信?
系统实现
Messenger
AIDL:Android Interface definition language
3. Messenger方式 ① 适用情况
多进程+单线程
② 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class MessengerService extends Service { public static final String TAG = MessengerService.class.getSimpleName(); Messenger messenger = new Messenger(new CommunicationHandler()); @SuppressLint("HandlerLeak") class CommunicationHandler extends Handler { @Override public void handleMessage (@NonNull Message msg) { super .handleMessage(msg); switch (msg.what){ case 0 : Log.d(TAG,msg.arg1+"---" ); Toast.makeText(MessengerService.this , "数据:" +msg.arg1, Toast.LENGTH_SHORT).show(); break ; default : throw new IllegalStateException("Unexpected value: " + msg.what); } } } @Nullable @Override public IBinder onBind (Intent intent) { return messenger.getBinder(); } } <service android:name=".MessengerService" android:process="swu.xl.messenger.service" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class MainActivity extends AppCompatActivity { public static final String TAG = MessengerService.class.getSimpleName(); private Messenger messenger; private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected (ComponentName name, IBinder service) { messenger = new Messenger(service); Message message = Message.obtain(); message.what = 0 ; message.arg1 = 10 ; try { messenger.send(message); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(MainActivity.this , "远程异常" , Toast.LENGTH_SHORT).show(); } } @Override public void onServiceDisconnected (ComponentName name) { } }; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindService( new Intent(this ,MessengerService.class), serviceConnection, Context.BIND_AUTO_CREATE ); } }
③ 进程图
④ 运行效果图
4. AIDL方式 ① 适用情况
多进程+多线程
② 代码
1> 在模块名.src.main
创建 aidl 文件夹,在该文件夹中创建AIDL
文件,系统会自动帮我们自动创建一个包,如下图所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 package swu.xl.aidl;interface IMyAidlInterface { void basicTypes (int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) ;}
2> 使用Build -> Make Project
,让系统自动生成代码,生成代码的位置如下图所示:
3> 在aidl
文件中,构建自己想要传递数据的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package swu.xl.aidl;interface IMyAidlInterface { void basicTypes (int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) ; String getName (String nickName) ; }
此时,还需要 Build -> Make Project
,因为添加了新的内容,所以需要重新生成代码。
4> 创建在新的进程的一个服务,和MainActivity进行通信。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class AIDLService extends Service { IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() { @Override public void basicTypes (int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override public String getName (String nickName) throws RemoteException { return nickName+"你好" ; } }; @Nullable @Override public IBinder onBind (Intent intent) { return stub; } }
1 2 3 <service android:name=".AIDLService" android:process=":aidl" />
5> MainActivity中的调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class MainActivity extends AppCompatActivity { private IMyAidlInterface iMyAidlInterface; private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected (ComponentName name, IBinder service) { iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected (ComponentName name) { } }; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindService(new Intent(this ,AIDLService.class), serviceConnection, Context.BIND_AUTO_CREATE); findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { if (iMyAidlInterface != null ){ try { String test = iMyAidlInterface.getName("test" ); Toast.makeText(MainActivity.this , "name:" +test, Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); } } } }); } }
1 2 3 public static swu.xl.aidl.IMyAidlInterface asInterface (android.os.IBinder obj)
6> 进程图
7> 运行效果图
5. 源代码 MultiProcess