`
kevinlynx
  • 浏览: 82298 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

Android: Activity、进程、BoradcastReceiver生命周期

阅读更多
Android中Activity和进程的生命周期是一个很重要的问题。Android对进程也采取了垃圾回收之类的机制,这意味着即使用户退出了程序,该进程依然可能存在于系统中。这将直接影响我们写的程序结构。


一个进程可能有若干个Activity。Activity退出后,进程可能并没有结束。下次用户从桌面启动该Activity时,会直接使用没有结束的进程。所以,想直接在主Activity中做程序初始化之类的操作,则需要小心。(实际上,Activity没有主次之分,说它是“主”,主要是因为它接受ndroid.intent.action.MAIN action)


如下代码:
package com.kl.test;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

class GlobalData {
	public static final String LOGTAG = "TestLog";
	private static GlobalData mInst = null;
	
	public static GlobalData instance() {
		if(mInst == null) {
			Log.d(LOGTAG, "The instance is null.");
			mInst = new GlobalData();
		}
		else {
			Log.d(LOGTAG, "The instance is ready.");
		}
		return mInst;
	}
}

public class Test2 extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Log.d(GlobalData.LOGTAG, "Activity onCreate.");
        GlobalData.instance();
        Observer.register(this);
    }
    
    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	Log.d(GlobalData.LOGTAG, "Activity onDestroy.");
    }
}


package com.kl.test;

import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;

/*
 * If the process has been terminated, the ContentObserver will not be called when
 * the content changed.
 * It's very same as Activity about life cycle.
 */
public class Observer extends ContentObserver {
	private static final Uri CONTENT_URI = Uri.parse("content://sms");
	private static boolean mRegistered = false;
	
	Observer(Handler h) {
		super(h);
	}
	
	@Override
	public void onChange( boolean selfChange ) {
		super.onChange(selfChange);
		Log.d(GlobalData.LOGTAG, "Observer onChange.");
		// test code.
		GlobalData.instance();
	}
	
	public static void register(Context context) {
		if(mRegistered) {
			Log.d(GlobalData.LOGTAG, "Observer already registered.");
			return;
		}
		mRegistered = true;
		context.getContentResolver().registerContentObserver(CONTENT_URI, true, 
				new Observer( new Handler() ) );
		Log.d(GlobalData.LOGTAG, "Observer register.");
	}
}



GlobalData算是我们程序的逻辑数据,当运行以上程序时,第一次会得到如下日志输出:

12-24 11:58:58.923: DEBUG/TestLog(223): Activity onCreate.
12-24 11:58:58.983: DEBUG/TestLog(223): The instance is null.
12-24 11:58:59.014: DEBUG/TestLog(223): Observer register.


ContentObserver是当监听的content发生变化时,被回调。当按BACK回到桌面,并再次启动该程序时,则得到:

12-24 12:09:14.113: DEBUG/TestLog(223): Activity onCreate.
12-24 12:09:14.134: DEBUG/TestLog(223): The instance is ready.
12-24 12:09:14.154: DEBUG/TestLog(223): Observer already registered.


从上可以证实:

就算是activity都退出了,进程也不一定结束。进程不结束,进程内的静态数据就不会消失。


进程什么时候被终止?根据官方文档描述,一个重要的条件是,当系统发觉内存过少时,则会把一些没有处于前台的activity进程结束掉。我们可以使用DDMS直接终止进程。终止进程后,再启动activity,则会得到第一次的日志输出。


值得注意的是,如果我们的进程结束掉了,那么注册的ContentObserver则不会被调用。相反,如果进程依然存在,就算没有activity,ContentObserver也会被调用,并且不会创建其他activity。


此外,对于BroadcastReceiver:
package com.kl.test;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/*
 * It will called even if the process has been terminated before. After it is called,
 * the process will remain as usual for sometime.
 */
public class SmsReceiver extends BroadcastReceiver {
	  @Override
	  public void onReceive(Context context, Intent intent) {
		  Log.d(GlobalData.LOGTAG, "SmsReceiver onReceive.");
		  GlobalData.instance();
	  } 
}




就算进程不在,BroadcastReceiver也会被调用,并且创建对应的进程。但是,并不会创建任何Activity。




BTW,activity中的数据会由于activity被销毁而被销毁。activity onDestroy了就真的是被destory了,意味着其在内存中的消失。在UI中缓存UI界面数据的需要注意一下。


PS,优化后的程序在进程已经存在的情况下,效率明显提升。:D


1.16.2011 update

BroadcastReceiver被调用时,会首先初始化所在的进程(如果进程之前被关闭),也就是会执行Application:onCreate
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics