您的位置:首页 > 移动开发 > Android开发

android2.2源码初探

2012-01-14 14:17 567 查看
由于代码中涉及到UI的布局,不得已看android源码。

源码系android-8即2.2

从调试环境看最初调用NativeStart.java中的main函数,经过底层的若干次调用,途经ActivityThread.java中的main函数调用,代码如下:

[code]     [code]public static final void main(String[] args) {


SamplingProfilerIntegration.start();


 


Process.setArgV0("<pre-initialized>");


 


Looper.prepareMainLooper();


 


ActivityThread thread = new ActivityThread();


thread.attach(false);


 


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");


}

[/code]
[/code]

这儿应是程序的起点,Looper.loop()展示的为相关的消息处理机制。使得程序不像普通的main函数一样立刻就结束了。

Looper.java中loop()就是一个消息循环,代码如下:

[code]
[code]/**


*  Run the message queue in this thread. Be sure to call


* {@link #quit()} to end the loop.


*/


public static final void loop() {


Looper me = myLooper();


MessageQueue queue = me.mQueue;


while (true) {


Message msg = queue.next(); // might block


//if (!me.mRun) {


//    break;


//}


if (msg != null) {


if (msg.target == null) {


// No target is a magic identifier for the quit message.


return;


}


if (me.mLogging!= null) me.mLogging.println(


">>>>> Dispatching to " + msg.target + " "


+ msg.callback + ": " + msg.what


);


msg.target.dispatchMessage(msg);


if (me.mLogging!= null) me.mLogging.println(


"<<<<< Finished to    " + msg.target + " "


+ msg.callback);


msg.recycle();


}


 }


}

[/code]
[/code]

顺便把怎样结束消息循环的代码也贴出来,方便对照消息开始的地方。

[code]
[code]public void quit() {


Message msg = Message.obtain();


// NOTE: By enqueueing directly into the message queue, the


// message is left with a null target.  This is how we know it is


// a quit message.


mQueue.enqueueMessage(msg, 0);


}

[/code]
[/code]

接着看Handler.java

[code]
[code]/**


* Handle system messages here.


*/


public void dispatchMessage(Message msg) {


if (msg.callback != null) {


handleCallback(msg);


 } else {


if (mCallback != null) {


if (mCallback.handleMessage(msg)) {


return;


}


}


handleMessage(msg);


 }


}

[/code]
[/code]

 

handleMessage()我们在写消息处理的时候经常用到,看ViewRoot.java中,

[code]
[code]@Override


public void handleMessage(Message msg) {


switch (msg.what) {


case View.AttachInfo.INVALIDATE_MSG:


((View) msg.obj).invalidate();


break;


case View.AttachInfo.INVALIDATE_RECT_MSG:


final View.AttachInfo.InvalidateInfo info = (View.AttachInfo.InvalidateInfo) msg.obj;


info.target.invalidate(info.left, info.top, info.right, info.bottom);


info.release();


break;


case DO_TRAVERSAL:


if (mProfile) {


Debug.startMethodTracing("ViewRoot");


}


 


performTraversals();


 


if (mProfile) {


Debug.stopMethodTracing();


mProfile = false;


}


break;


case FINISHED_EVENT:


handleFinishedEvent(msg.arg1, msg.arg2 != 0);


break;


case DISPATCH_KEY:


if (LOCAL_LOGV) Log.v(


"ViewRoot", "Dispatching key "


+ msg.obj + " to " + mView);


deliverKeyEvent((KeyEvent)msg.obj, true);


break;


case DISPATCH_POINTER: {


MotionEvent event = (MotionEvent)msg.obj;


boolean callWhenDone = msg.arg1 != 0;




if (event == null) {


    try {


        long timeBeforeGettingEvents;


        if (MEASURE_LATENCY) {


  timeBeforeGettingEvents = System.nanoTime();


}


 


        event = sWindowSession.getPendingPointerMove(mWindow);


 


        if (MEASURE_LATENCY && event != null) {


  lt.sample("9 Client got events      ", System.nanoTime() - event.getEventTimeNano());


  lt.sample("8 Client getting events  ", timeBeforeGettingEvents - event.getEventTimeNano());


}


} catch (RemoteException e) {


}


    callWhenDone = false;


}


if (event != null && mTranslator != null) {


    mTranslator.translateEventInScreenToAppWindow(event);


}


try {


    boolean handled;


    if (mView != null && mAdded && event != null) {


 


        // enter touch mode on the down


        boolean isDown = event.getAction() == MotionEvent.ACTION_DOWN;


        if (isDown) {


  ensureTouchMode(true);


}


        if(Config.LOGV) {


  captureMotionLog("captureDispatchPointer", event);


}


        if (mCurScrollY != 0) {


  event.offsetLocation(0, mCurScrollY);


}


        if (MEASURE_LATENCY) {


  lt.sample("A Dispatching TouchEvents", System.nanoTime() - event.getEventTimeNano());


}


        handled = mView.dispatchTouchEvent(event);


        if (MEASURE_LATENCY) {


  lt.sample("B Dispatched TouchEvents ", System.nanoTime() - event.getEventTimeNano());


}


        if (!handled && isDown) {


  int edgeSlop = mViewConfiguration.getScaledEdgeSlop();


 


  final int edgeFlags = event.getEdgeFlags();


  int direction = View.FOCUS_UP;


  int x = (int)event.getX();


  int y = (int)event.getY();


  final int[] deltas = new int[2];


 


  if ((edgeFlags & MotionEvent.EDGE_TOP) != 0) {


      direction = View.FOCUS_DOWN;


      if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {


deltas[0] = edgeSlop;


x += edgeSlop;


} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {


deltas[0] = -edgeSlop;


x -= edgeSlop;


}


} else if ((edgeFlags & MotionEvent.EDGE_BOTTOM) != 0) {


      direction = View.FOCUS_UP;


      if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {


deltas[0] = edgeSlop;


x += edgeSlop;


} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {


deltas[0] = -edgeSlop;


x -= edgeSlop;


}


} else if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {


      direction = View.FOCUS_RIGHT;


} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {


      direction = View.FOCUS_LEFT;


}


 


  if (edgeFlags != 0 && mView instanceof ViewGroup) {


      View nearest = FocusFinder.getInstance().findNearestTouchable(


    ((ViewGroup) mView), x, y, direction, deltas);


      if (nearest != null) {


event.offsetLocation(deltas[0], deltas[1]);


event.setEdgeFlags(0);


mView.dispatchTouchEvent(event);


}


}


}


}


} finally {


    if (callWhenDone) {


        try {


  sWindowSession.finishKey(mWindow);


} catch (RemoteException e) {


}


}


    if (event != null) {


        event.recycle();


}


    if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!");


    // Let the exception fall through -- the looper will catch


    // it and take care of the bad app for us.


}


} break;


case DISPATCH_TRACKBALL:


deliverTrackballEvent((MotionEvent)msg.obj, msg.arg1 != 0);


break;


case DISPATCH_APP_VISIBILITY:


handleAppVisibility(msg.arg1 != 0);


break;


case DISPATCH_GET_NEW_SURFACE:


handleGetNewSurface();


break;


case RESIZED:


ResizedInfo ri = (ResizedInfo)msg.obj;


 


if (mWinFrame.width() == msg.arg1 && mWinFrame.height() == msg.arg2


        && mPendingContentInsets.equals(ri.coveredInsets)


        && mPendingVisibleInsets.equals(ri.visibleInsets)


        && ((ResizedInfo)msg.obj).newConfig == null) {


    break;


}


// fall through...


case RESIZED_REPORT:


if (mAdded) {


    Configuration config = ((ResizedInfo)msg.obj).newConfig;


    if (config != null) {


        updateConfiguration(config, false);


}


    mWinFrame.left = 0;


    mWinFrame.right = msg.arg1;


    mWinFrame.top = 0;


    mWinFrame.bottom = msg.arg2;


    mPendingContentInsets.set(((ResizedInfo)msg.obj).coveredInsets);


    mPendingVisibleInsets.set(((ResizedInfo)msg.obj).visibleInsets);


    if (msg.what == RESIZED_REPORT) {


        mReportNextDraw = true;


}


 


    if (mView != null) {


        forceLayout(mView);


}


    requestLayout();


}


break;


case WINDOW_FOCUS_CHANGED: {


if (mAdded) {


    boolean hasWindowFocus = msg.arg1 != 0;


    mAttachInfo.mHasWindowFocus = hasWindowFocus;


    if (hasWindowFocus) {


        boolean inTouchMode = msg.arg2 != 0;


        ensureTouchModeLocally(inTouchMode);


 


        if (mGlWanted) {


  checkEglErrors();


  // we lost the gl context, so recreate it.


  if (mGlWanted && !mUseGL) {


      initializeGL();


      if (mGlCanvas != null) {


float appScale = mAttachInfo.mApplicationScale;


mGlCanvas.setViewport(


        (int) (mWidth * appScale + 0.5f),


        (int) (mHeight * appScale + 0.5f));


}


}


}


}


 


    mLastWasImTarget = WindowManager.LayoutParams


  .mayUseInputMethod(mWindowAttributes.flags);


 


    InputMethodManager imm = InputMethodManager.peekInstance();


    if (mView != null) {


        if (hasWindowFocus && imm != null && mLastWasImTarget) {


  imm.startGettingWindowFocus(mView);


}


        mAttachInfo.mKeyDispatchState.reset();


        mView.dispatchWindowFocusChanged(hasWindowFocus);


}


 


    // Note: must be done after the focus change callbacks,


    // so all of the view state is set up correctly.


    if (hasWindowFocus) {


        if (imm != null && mLastWasImTarget) {


  imm.onWindowFocus(mView, mView.findFocus(),


mWindowAttributes.softInputMode,


!mHasHadWindowFocus, mWindowAttributes.flags);


}


        // Clear the forward bit.  We can just do this directly, since


        // the window manager doesn't care about it.


        mWindowAttributes.softInputMode &=


      ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;


        ((WindowManager.LayoutParams)mView.getLayoutParams())


      .softInputMode &=


~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;


        mHasHadWindowFocus = true;


}


 


    if (hasWindowFocus && mView != null) {


        sendAccessibilityEvents();


}


}


} break;


case DIE:


doDie();


break;


case DISPATCH_KEY_FROM_IME: {


if (LOCAL_LOGV) Log.v(


"ViewRoot", "Dispatching key "


    + msg.obj + " from IME to " + mView);


KeyEvent event = (KeyEvent)msg.obj;


if ((event.getFlags()&KeyEvent.FLAG_FROM_SYSTEM) != 0) {


    // The IME is trying to say this event is from the


    // system!  Bad bad bad!


    event = KeyEvent.changeFlags(event,


  event.getFlags()&~KeyEvent.FLAG_FROM_SYSTEM);


}


deliverKeyEventToViewHierarchy((KeyEvent)msg.obj, false);


} break;


case FINISH_INPUT_CONNECTION: {


InputMethodManager imm = InputMethodManager.peekInstance();


if (imm != null) {


    imm.reportFinishInputConnection((InputConnection)msg.obj);


}


} break;


case CHECK_FOCUS: {


InputMethodManager imm = InputMethodManager.peekInstance();


if (imm != null) {


    imm.checkFocus();


}


} break;


case CLOSE_SYSTEM_DIALOGS: {


if (mView != null) {


    mView.onCloseSystemDialogs((String)msg.obj);


}


} break;


}


 }

[/code]
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: