2011-9-22 15:41:21
getPreferences 莫非有BUG?
SurfaceHolder 的回调
surfaceCreated
surfaceChanged
surfaceDestroyed
/**
* A client may implement this interface to receive information about
* changes to the surface. When used with a {@link SurfaceView}, the
* Surface being held is only available between calls to
* {@link #surfaceCreated(SurfaceHolder)} and
* {@link #surfaceDestroyed(SurfaceHolder). The Callback is set with
* {@link SurfaceHolder#addCallback SurfaceHolder.addCallback} method.
*/
public interface Callback {
/**
* This is called immediately after the surface is first created.
* Implementations of this should start up whatever rendering code
* they desire. Note that only one thread can ever draw into
* a {@link Surface}, so you should not draw into the Surface here
* if your normal rendering will be in another thread.
*
* @param holder The SurfaceHolder whose surface is being created.
*/
在另外一个线程里进行绘画
public void surfaceCreated(SurfaceHolder holder);
/**
* This is called immediately after any structural changes (format or
* size) have been made to the surface. You should at this point update
* the imagery in the surface. This method is always called at least
* once, after {@link #surfaceCreated}.
*
* @param holder The SurfaceHolder whose surface has changed.
* @param format The new PixelFormat of the surface.
* @param width The new width of the surface.
* @param height The new height of the surface.
*/
发生了改变
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height);
/**
* This is called immediately before a surface is being destroyed. After
* returning from this call, you should no longer try to access this
* surface. If you have a rendering thread that directly accesses
* the surface, you must ensure that thread is no longer touching the
* Surface before returning from this function.
*
* @param holder The SurfaceHolder whose surface is being destroyed.
*/
//surface 现在关闭
public void surfaceDestroyed(SurfaceHolder holder);
}
mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
SurfaceView和mSurfaceHolder之间的关系
/**
* Finds a view that was identified by the id attribute from the XML that
* was processed in {@link #onCreate}.
*
* @return The view if found or null otherwise.
*/
public View findViewById(int id) {
return getWindow().findViewById(id);
}
/**
* Set the activity content from a layout resource. The resource will be
* inflated, adding all top-level views to the activity.
*
* @param layoutResID Resource ID to be inflated.
*/
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
}
ContextThemeWrapper
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
Object lastNonConfigurationInstance,
HashMap<String,Object> lastNonConfigurationChildInstances,
Configuration config) {
attachBaseContext(context);
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mIdent = ident;
mApplication = application;
mIntent = intent;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstance = lastNonConfigurationInstance;
mLastNonConfigurationChildInstances = lastNonConfigurationChildInstances;
mWindow.setWindowManager(null, mToken, mComponent.flattenToString());
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
入口点
public static final void main(String[] args) {
SamplingProfilerIntegration.start();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
Slog.i(TAG, "Main thread of " + name + " is now exiting");
}
把本对象设置成tls
final ApplicationThread mAppThread = new ApplicationThread();
你还创建了一个ApplicationThread对象
Activity Service ?
ActivityManager !
首先,从SDK中和源码中都可以获知,ActivityGroup类的父类是Activity,也就是说二者具有相同的接口和生命周期,同Activity一样,也有onCreate()、onPause()等函数可供我们重载。
父类
在ActivityGroup的源码中有成员变量
protected LocalActivityManager mLocalActivityManager;
该变量在ActivityGroup的构造函数中创建并初始化,可见,ActivityGroup的功能实现肯定是要委托给这个对象来完成了。为了给用户开放对此对象的访问,ActivityGroup提供了
public final LocalActivityManager getLocalActivityManager() {
return mLocalActivityManager;
}
本地对象管理
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle states = savedInstanceState != null
? (Bundle) savedInstanceState.getBundle(STATES_KEY) : null;
mLocalActivityManager.dispatchCreate(states);
}
下面,我们就来看一下LocalActivityManager的源码。
在该类中,提供了一个私有类
private static class LocalActivityRecord extends Binder {
LocalActivityRecord(String _id, Intent _intent) {
id = _id;
intent = _intent;
}
final String id; // Unique name of this record.
Intent intent; // Which activity to run here.
ActivityInfo activityInfo; // Package manager info about activity.
Activity activity; // Currently instantiated activity.
Window window; // Activity's top-level window.
Bundle instanceState; // Last retrieved freeze state.
int curState = RESTORED; // Current state the activity is in.
}
用于保存Activity的信息,并提供了
private final Map<String, LocalActivityRecord> mActivities
= new HashMap<String, LocalActivityRecord>();
private final ArrayList<LocalActivityRecord> mActivityArray
= new ArrayList<LocalActivityRecord>();
采用这样的数据结构用于对所有嵌入的子Activity信息进行保存处理。其中前者用于通过String快速查找,后者用于以数组的方式快速访问,是典型的以空间换时间的的方式。
hashmap和数组
public void dispatchCreate(Bundle state) {
if (state != null) {
final Iterator<String> i = state.keySet().iterator();
while (i.hasNext()) {
try {
final String id = i.next();
final Bundle astate = state.getBundle(id);
LocalActivityRecord r = mActivities.get(id);
if (r != null) {
r.instanceState = astate;
} else {
r = new LocalActivityRecord(id, null);
r.instanceState = astate;
mActivities.put(id, r);
mActivityArray.add(r);
}
} catch (Exception e) {
……
}
}
}
mCurState = CREATED;
}
dispatchCreate
从这里我们可以看出,当有一个ActivityGroup被Create的时候,就会有对应的Activity信息被保存到数组中。
当我们调用LocalActivityManager的startActivity()以产生Window的时候,我们也可以看到
public Window startActivity(String id, Intent intent) {
……
LocalActivityRecord r = mActivities.get(id);
if (r == null) {
r = new LocalActivityRecord(id, intent);
adding = true;
}
……
if (adding) {
mActivities.put(id, r);
mActivityArray.add(r);
}
……
}
有了这个数组,就可以遍历到ActivityGroup中嵌入的Activitys了,从而可以实现ActivityGroup的功能。
以上的分析结果产生的类图如下:
dispatchCreate
public ActivityGroup(boolean singleActivityMode) {
mLocalActivityManager = new LocalActivityManager(this, singleActivityMode);
}