Android 应用内多进程实现 单APK应用多进程

来源:互联网 发布:csgo淘宝买饰品 编辑:程序博客网 时间:2024/06/06 01:31
Android平台支持多进程通信,也支持应用内实现多进程,Android中,默认一个APK包就对应一个进程,其进程名就为AndroidManifest.xml文件中 指定的package名。我们可以通过Activity,Service,BroadCastReceiver,ContentProvider的android:process属性来实现单APK多进程,但是需要注意进程间内存的不可见性。

我们都知道,android平台对应用都有内存限制,其实这个理解有点问题,应该是说android平台对每个进程有内存限制,比如某机型对对进程限制是24m,如果应用有两个进程,则该应该的总内存限制是2*24m。使用多进程就可以使得我们一个apk所使用的内存限制加大几倍。
所以可以借此突破对应用的内存限制,比如一些要对图片、视频、大文件进程处理的好内存的应用可以考虑用多进程来解决应用操作不流畅问题。

实现多进程可以通过设置service、broadcast、activity的标签android:process来实现。
一般情况下启动这些组件默认是在同一个进程里运行的,如果设置了android:process标签,则会运行在其他进程里。
如果android:process的value不是":"开头,则系统里有同样名字的进程的话,会放到已存在的同名进程里运行,这样能减小消耗。
如果android:process的value是以":"开头,则启动一个名字为value的进程。

实现应用多进程之后,就是进程间通信啦,进程间通信有两种实现方式:
1、用系统框架实现:系统框架实现进程通信有用过Service,Broadcast,Activity,ContentProvider。
2、自己实现AIDL。

Android使用多进程实例:

MainActivity.java

package com.haier.oet.androidplayerground;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;public class MainActivity2 extends Activity {    static boolean iscreated=false;    final static String TAG="ysm";    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        iscreated=true;        Log.i(TAG,"on create() in MainActivity");        this.startService(new Intent(this,MyService.class));    }}

MyService.java

package com.haier.oet.androidplayerground;/** * Created by oet on 16/4/13. */import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class MyService extends Service {    String tag="ysm";    @Override    public void onCreate() {        Log.i(tag,"MyService is oncreate");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.i(tag, "MainActivity is created: " + MainActivity2.iscreated);        return START_STICKY;    }    @Override    public void onDestroy() {        Log.i(tag,"OnDestory");    }    @Override    public IBinder onBind(Intent arg0) {        return null;    }}

layout\activity_main.xml

<RelativeLayout 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" >    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true"        android:text="@string/hello_world"        tools:context=".MainActivity" /></RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest package="com.haier.oet.androidplayerground"          xmlns:android="http://schemas.android.com/apk/res/android">    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity            android:name=".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=".MyService"            android:label="@string/title_activity_main"            android:process="com.haier.ysm.test.service">        </service>    </application></manifest>

values\strings.xml

<resources>    <string name="app_name">Test</string>    <string name="hello_world">Hello world!</string>    <string name="menu_settings">Settings</string>    <string name="title_activity_main">MainActivity</string></resources>

运行该应用程序
DDMS截图显示的进程如下:


运行打印出的日志如下:

04-13 15:07:32.811 10762-10762/com.haier.oet.androidplayerground I/robin: on create() in MainActivity04-13 15:07:32.831 10762-10762/com.haier.oet.androidplayerground I/robin: MyService is oncreate04-13 15:07:32.831 10762-10762/com.haier.oet.androidplayerground I/robin: MainActivity is created: true

我们对AndroidManifest.xml文件进行修改,以实现当APK应用多进程。
修改后的AndroidManifest.xml文件如下:

<?xml version="1.0" encoding="utf-8"?><manifest package="com.haier.oet.androidplayerground"          xmlns:android="http://schemas.android.com/apk/res/android">    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity            android:name=".MainActivity2"            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=".MyService"            android:label="@string/title_activity_main"            android:process="com.haier.ysm.test.service">        </service>    </application></manifest>

DDMS截图显示的进程如下:


运行打印出的日志如下:

04-13 15:13:48.161 18420-18420/? I/ysm: on create() in MainActivity04-13 15:13:48.242 18435-18435/? I/ysm: MyService is oncreate04-13 15:13:48.242 18435-18435/? I/ysm: MainActivity is created: false

虽然我们在MainActivity的onCreate中把iscreated变量设置为了true,因为进程间内存的不可见性,,所以才会打印日志“MainActivity is created: false”。
简单点说就是每个进程都是运行在不同的虚拟机上,对于不同的进程,他们载入的Class文件虽然名字一样(比如都是com.haier.oet.androidplayerground.MainActivity),但是他们其实是加载到了不同的内存地址空间。
com.haier.oet.androidplayerground.MainActivity中把iscreated变量设置为true,它其实只是把当前进程(com.haier.oet.androidplayerground.test)的MainActivity类的iscreated变量的设置为了true,
com.haier.oet.androidplayerground.service进程中的 com.haier.oet.androidplayerground.MainActivity 类和它位于不同的内存地址空间,当然其变量iscreated也位于不同的内存地址空间,自然也不受影响。



1 0