代码改变世界

android:process结合activity启动模式的一次实践

2014-08-20 20:36  ttylinux  阅读(2336)  评论(0编辑  收藏  举报

        会有这样的场景,一个应用崩溃了,而导致的该应用崩溃的原因是,该应用占用的内存大小超过了系统分配给它的最大堆大小。对象的分配,是发生在堆(heap)上面的,系统分配给每个应用的最大堆大小是固定的。

        假设,出现这种情况了,你的应用再启动一个activity,就导致了你的应用崩溃了,你的应用使用的内存超过了系统分配的最大堆大小。那么,这个时候,可以采取做法是,优化算法之类的,但是,假设,你优化了,但是,依然出现这个问题。

        那么,可以采取这种做法:让被启动的Activity运行在一个新的独立进程中,这样,这个启动的Activity实例,它就不占用你的应用的堆大小。这可以通过android:process来实现。这是一种解决应用因为占用的内存超过了系统的最大堆大小而导致的崩溃问题。

        另外,设置一个Activity的启动模式,设置它的启动模式是android:singleInstance,可以确保,即使用户多次调用该Activity,但是,系统中只有一个实例,而不会多次创建。这也是一种节约内存的方式。

        下面是实践:

         实践的要求

        1.创建一个应用,该应用,由该应用启动HelpActivity.

        2.HelpActivity设置运行在一个独立的进程中。

        3.helpActivity限定在一个独立的task中运行
        4.启动和helpActivity,确保它在系统中运行时只有一个实例,即使用户多次调用它。
        5.用DDMS验证实际的HelpActivity所在的进程,是不是与启动它的应用的进程,不是同一个。
       
-----------具体实践内容
        配置方面:
 
        1.android:taskAffinity可以确保该Activity运行在一个独立的Task中
        2.android:launchMode ="singleInstance",可以确保,在任何时刻,该Activity实例只有一个,即使用户多次启动它。
     
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.processtest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.processtest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".HelpActivity"
            android:launchMode="singleInstance"
            android:process=":a_separate_process"
            android:taskAffinity="com.processtest.myHelpActivity" />
    </application>

</manifest>

       

代码方面:

         1.要设置启动模式标识Intent.FLAG_ACTIVITY_NEW_TASK,目的就是实现单实例Activity。

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        inital();
    }
    
    private void inital()
    {
        Button start = (Button)findViewById(R.id.startHelp);
        start.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent = new Intent(MainActivity.this,HelpActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
            }
        });
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

 

   实际结果:
 
          DDMS中,显示:
          
         长按Home键:
         
 
       上述的信息,可以说明:
       1.二者是运行在不同的进程中。
       2.二者成为了两个不同的应用---由Home键显示的结果可以看出来。
 
 参考资料:
http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html
http://developer.android.com/tools/debugging/ddms.html
http://stackoverflow.com/questions/7142921/usage-of-androidprocess