編輯:關於Android編程
1. 首先調用Activity的startActivity,-1表示 target Activity finish的時候不通知original Activity
public void startActivity(Intent intent) {
startActivityForResult(intent, -1);
}
2 . 調用Activityd的startActivityForResult方法, Instrumentation class 裡面有一個ActivityMonitor 的內部類,用來監控view和system的交互
public void startActivityForResult(Intent intent, int requestCode) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
3. 調用Instrumentation class的 ExecStartActivity:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
// 如果找到匹配的Activity,am.mHits++
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
//調用ActivityManagerProxy的startActivity方法
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
4. ActivityManagerProxy 的startActivity的具體實現:
public int startActivity(IApplicationThread caller, Intent intent,
String resolvedType, Uri[] grantedUriPermissions, int grantedMode,
IBinder resultTo, String resultWho,
int requestCode, boolean onlyIfNeeded,
boolean debug) throws RemoteException {
// Parcel 本質上把它當成一個Serialize就可以了,只是它是在內存中完成的序列化和反序列化,利用的是連續的內存空間(這裡不要作為重點)
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeTypedArray(grantedUriPermissions, 0);
data.writeInt(grantedMode);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(onlyIfNeeded ? 1 : 0);
data.writeInt(debug ? 1 : 0);
//具體請參照後面的代碼 (這個函數只看到這裡就好了!!!)
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
//清除sOwnedPool中parcel對象,返回一個新的parcel
public static Parcel obtain() {
final Parcel[] pool = sOwnedPool;
synchronized (pool) {
Parcel p;
for (int i=0; i<POOL_SIZE; i++) {
p = pool[i];
if (p != null) {
pool[i] = null;
if (DEBUG_RECYCLE) {
p.mStack = new RuntimeException();
}
return p;
}
}
}
return new Parcel(0);
}
// 清除pool中存儲parcel,通過jni free剛才分配的內存
public final void recycle() {
if (DEBUG_RECYCLE) mStack = null;
freeBuffer();
final Parcel[] pool = mOwnObject != 0 ? sOwnedPool : sHolderPool;
synchronized (pool) {
for (int i=0; i<POOL_SIZE; i++) {
if (pool[i] == null) {
pool[i] = this;
return;
}
}
}
}
//
private native void freeBuffer();
// mRemote 實際通過ActivityManagerNative.getDefault進行注冊的,實際就是ActivityManagerService
static public IActivityManager getDefault()
{
if (gDefault != null) {
//if (Config.LOGV) Log.v(
// "ActivityManager", "returning cur default = " + gDefault);
return gDefault;
}
IBinder b = ServiceManager.getService("activity");
if (Config.LOGV) Log.v(
"ActivityManager", "default service binder = " + b);
gDefault = asInterface(b);
if (Config.LOGV) Log.v(
"ActivityManager", "default service = " + gDefault);
return gDefault;
}
5. 實際調用proxy中的Ontransact方法
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR);
int grantedMode = data.readInt();
IBinder resultTo = data.readStrongBinder();
String resultWho = data.readString();
int requestCode = data.readInt();
boolean onlyIfNeeded = data.readInt() != 0;
boolean debug = data.readInt() != 0;
int result = startActivity(app, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded, debug);
reply.writeNoException();
reply.writeInt(result);
return true;
}
6 . startActivity 實際調用ActivityManagerService中的startActivity方法
由於StartActivity太長,拿關鍵部分分享
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
int res = startActivityLocked(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, aInfo,
resultTo, resultWho, requestCode, -1, -1,
onlyIfNeeded, componentSpecified);
Binder.restoreCallingIdentity(origId);
return res;
}
7. startActivityLocked實際調用ApplicationThread中scheduleLaunchActivity
public final void scheduleLaunchActivity(Intent intent, IBinder token,
ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {
ActivityRecord r = new ActivityRecord();(histroyRicord)
r.token = token;
r.intent = intent;
r.activityInfo = info;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward; www.2cto.com
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
8. queueOrSendMessage 然後發消息給ActivityThread 的Handler
case LAUNCH_ACTIVITY: {
ActivityRecord r = (ActivityRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo);
handleLaunchActivity(r);
} break;
具體調用
private final Activity performLaunchActivity(ActivityRecord r) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
***
mInstrumentation.callActivityOnCreate(activity, r.state);
***
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
上一篇我們說到的逐幀動畫和補間動畫,這篇我們著重說下屬性動畫:先看下面兩幅動畫: 上面兩幅動畫就是通過屬性動畫做出來的,是不是比較炫呢!不僅有顯示,也有交互點擊事件。下面
前言還記得之前我們寫了一篇文章,基於RxJava實現酷炫啟動頁,然而當我們點擊桌面圖標啟動APP時,有時會閃一下黑色背景,有時黑色背景時間還比較長,哎呀,難看死了,這個怎
前言 用過微信的都知道,微信對話列表滑動刪除效果是很不錯的,這個效果我們也可以有。思路其實很簡單,弄個ListView,然後裡面的每個item做成一個可以滑動的
Service概念及用途:Android中的服務,它與Activity不同,它是不能與用戶交互的,不能自己啟動的,運行在後台的程序,如果我們退出應用時,Service進程