완전히 아직 안드로이드 개발을하는 방법을 알고하지 않습니다 결국 어떤 상황을 이해하도록 기사?

머리말

오늘 우리는 APP의 개발에, 우리는 종종 컨텍스트를 사용, 소스 코드의 문맥을 분석, 컨텍스트 다음은 무엇인가? 다음 "컨텍스트"그것이 무엇 결국 "컨텍스트"그것의 일반적인 의미입니까? 소스 코드를 분석함으로써, 우리는이 상황에 대한 기본적인 이해를 가질 수 있습니다.

클래스 상속 그래프

우리는 문맥에 클래스 상속 그래프를 보면, 우리는 소스 코드를보고 배우고, 컨텍스트는 추상 클래스는 확실히 구현 클래스가 그래서 그것의 상속 그래프는 다음 있도록, ContextWrapper 및 ContextImpl 자사의 구현 클래스를 검토한다 :

완전히 아직 안드로이드 개발을하는 방법을 알고하지 않습니다 결국 어떤 상황을 이해하도록 기사?

상속의 컨텍스트 클래스보다 간결 정의, 응용 프로그램, 서비스, 활동 컨텍스트 클래스는 우리가 볼 수 있도록 여기에서, 상속 배울 수 있습니다 :

Context 数量 = Activity 数量 + Service 数量 + 1

또한,이 이유는, 우리는 응용 프로그램을 볼 수 있습니다 및 활동이 ContextThemeWrapper을 상속하는 동안 서비스를 직접 ContextWrapper을 상속? 사실 ContextThemeWrapper는 활동 인터페이스, 그리고 응용 프로그램 및 서비스는하지 않았다, 대상 클래스에 있습니다. 우리는 그들의 소스 코드 구현을 자세히 살펴 온 다음으로.

ContextWrapper

우리는 찾을 수 있습니다 ContextWrapper 소스에 입력, 그것은 실제로 메서드 내 mBase라고하며, mBase 사실 ContextImpl, 그래서 결국 방법 내부의 구현 클래스 ContextImpl 클래스를 호출해야합니다.

public class ContextWrapper extends Context {
    Context mBase;
    public ContextWrapper(Context base) {
        mBase = base;
    }
    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }
    //其余的都是覆盖Context里面的方法
}

그들은 관련 ContextImpl에 관련되어 있어야로서 우리는 응용 프로그램 및 서비스 활동 때문에뿐만 아니라, 실제로 ContextWrapper 호출 ContextImpl의 내부를 알 수 위의 방법 다음에 위 클래스 상속 그래프 분석을 수행 할 수 있습니다. 결국 그렇지는 경우가? 우리는 소스 코드 분석을 추적 할 수 있습니다.

신청

시작 자바 프로그램과 유사 주요 방법은 안드로이드 ActivityThread 클래스의 것과 유사한 방법이 또한 메인, 이것은 우리가 여기에서 조금 트랙 있었다 시작하는 곳이 있습니다

ActivityThread 번호 메인

      //省略部分代码...
      Looper.prepareMainLooper();
      ActivityThread thread = new ActivityThread();
      thread.attach(false);
      //省略部分代码...
      Looper.loop();      
      //省略部分代码...

우리는 관계없이 코드의 주요 방법은 지속적으로 메시지 큐에서 메시지를 얻을 수 있습니다, 생략, 후 처리, 주요 방법 ActivityThread을 찾을 수 있습니다. 우리는 방법을 첨부 계속 입력, 내용 만의 상황 분석과 관련이 물건 루퍼를 분석하지 않습니다

안드로이드 소스 코드 분석은하지 급락, 우리는 그것의 주요 프로세스를 분석해야합니다.

ActivityThread 번호가 부착

//省略部分代码...
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                //Application的实例创建
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);

                //调用Application里面的生命周期方法onCreate
                mInitialApplication.onCreate();
//省略部分代码...

과정을 추적 할 makeApplication에 계속 있도록 다음은 응용 프로그램과 함께 할 수있는 뭔가해야하므로이는 ContextImpl 등장

LoadedApk # makeApplication

//省略部分代码...
  Application app = null;
 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
//省略部分代码...

결국, 어느 계측 # newApplication 방법으로

계측 # newApplication

static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

응용 프로그램 번호가 부착

    /**
    * @hide
    */
   /* package */ 
   final void attach(Context context) {
       attachBaseContext(context);
       mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
   }

분명 여기 와서, 그리고 마지막으로 ContextWrapper의 attachBaseContext 메소드를 호출합니다. 위의 여기에서 예상대로, 여기에 분석을 얼마나 기억 나? 응용 프로그램은이 방법을 attachBaseContext 결국 어떤 통화를 알고있다? 오른쪽이 경우, 코드가 너무 많이, 너무 많이, 하나 개의 세부 사항 하나 개 근본적인 분석 가능성, 우리는 다음 과정을 파악할 수 방향 감각을 잃은 것 바다, 주변의 여행, 안드로이드 소스 코드에 거꾸로 급락 할 수 없다 구현 프로세스를 재 타겟팅 분석. 다음 분석 방법은 서비스와 관련된.

서비스

서비스를 위해, 우리 ActivityThread는 handleCreateService라는 방법이 발견 될 수 있으며, 서비스 사이와 ContextImpl에 대한 링크가 있습니다.

ActivityThread # handleCreateService

Service service = null;
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
           context.setOuterContext(service);
           Application app = packageInfo.makeApplication(false, mInstrumentation);
           service.attach(context, this, data.info.name, data.token, app,
                   ActivityManager.getService());
           service.onCreate();

우리는 모두를 찾을 수 등을 할 수있는 코드의 응용 프로그램을 위해, 우리는 코드보기, 찾기로 연결 방법

/**
    * @hide
    */
   public final void attach(
           Context context,
           ActivityThread thread, String className, IBinder token,
           Application application, Object activityManager) {
    //调用attachBaseContext方法
       attachBaseContext(context);
       mThread = thread;           // NOTE:  unused - remove?
       mClassName = className;
       mToken = token;
       mApplication = application;
       mActivityManager = (IActivityManager)activityManager;
       mStartCompatibility = getApplicationInfo().targetSdkVersion
               < Build.VERSION_CODES.ECLAIR;
   }

코드 그게 ContextImpl와 아무 상관이있어, 매우 간단합니다. ContextWrapper 클래스의 서비스 및 응용 프로그램이 상속되기 때문에, 우리는의 활동에 코드를 분석해야합니다.

활동

다음은 서비스 및 응용 프로그램 ContextWrapper 활동 클래스 상속과 활동이 인터페이스에 표시되기 때문입니다 ContextThemeWrapper을 상속, 우리는 정보 ContextThemeWrapper 이름에서 주제를 포함하고 볼 수 있도록 서비스 및 응용 프로그램,하지 않았다 이유를 설명 ContextThemeWrapper하지만이 ContextWrapper에서 상속되는 동안, ContextThemeWrapper는 소스 코드 분석 우리는 방법의 주제에 대해 기본적으로 볼 수 있지만, 그것은 또한 attachBaseContext 방법을 설명합니다.

우리는 또한 활동 코드도 유사한 방법 및 서비스를 첨부 입력 발견

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,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
        //省略部分代码...
        attachBaseContext(context);

우리가 활동을 분석하고 다음이 아무 상관이 곳.

ActivityThread # performLaunchActivity

performLaunchActivity이 방법은 실제로 방법 활동을 시작하고, 나중에이 방법의 내용에 대해 배우고 와서, 그것은 문맥의 내용을 분석한다. 우리는이 방법을보기로 입력 :

//省略部分代码...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
//省略部分代码...
  activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
//省略部分代码...

먼저 다음 즉시 활동이 내부에 부착 createBaseContextForActivity 방법으로 ContextImpl을 만들 수 있습니다. 지금까지, 같은 주제에베이스의 응용 프로그램, 서비스 및 활동 상황에 맞는 소스에 대한. 우리는 몇 가지 구체적인 내용을 해결하기 위해 온 다음으로.

이해의 예

끝이 그들 사이의 차이에 따라서 응용 프로그램, 서비스 및 활동 상황 이후? 한편 getApplicationContext 및 getApplication는 (), 무슨 차이가 있습니까? 우리가 코드를 통해 확인 다음.

우리의 현재 프로젝트는 또한 응용 프로그램에서는 MyApplication에서 상속은 다음 Manifest.xml에 등록하는 새로운 클래스를 만들고,이 경우, 일부 초기화 작업을 일반적으로 사용자 지정 응용 프로그램 클래스이며, 코드는 다음입니다 :

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("androidos_analysis", "getApplicationContext()——> " + getApplicationContext());
        Log.d("androidos_analysis", "getBaseContext()       ——> " + getBaseContext());
    }
}

다음과 같이 인쇄 결과는 다음과 같습니다

getApplicationContext()——> com.ihidea.androidosanalysis.MyApp@9831cf9
getBaseContext()       ——> android.app.ContextImpl@13d643e

우리는 ContextImpl 왜이 있습니다 획득 한 우리는 getApplicationContext을 통해 얻을 때 우리는 응용 프로그램 인스턴스임을 확인 것을 발견하고, getBaseContext로? 우리는 그들의 실현 찾기를 참조

ContextWrapper # getBaseContext

/**
   * @return the base context as set by the constructor or setBaseContext
   */
  public Context getBaseContext() {
      return mBase;
  }

사실, 우리가 그들의 소스 위의 분석, 우리는 사실이 ContextImpl mBase 것을 알고있다. getApplicationContext

ContextWrapper # getApplicationContext

@Override
  public Context getApplicationContext() {
      return mBase.getApplicationContext();
  }

위의 분석을 통해, 우리는 사실 그 자체 그래서 응용 프로그램 컨텍스트 것을 알고, 이것은 반환 사람 그 자체입니다. 그래서 여기 getApplicationContext () 예에 대한 결과에서는 MyApplication 자체입니다.

때때로 우리는 어떤 차이가 않습니다 getApplicationContext와 다음, getApplication 내부에서이 코드의 사용을해야합니다? 우리는 로그에 대해 알게.

우리는 MainActivity가 다음에 두 줄의 코드를 인쇄 만들 :

MainActivity #에서 onCreate

Log.d("androidos_analysis", "getApplicationContext()——> " + getApplicationContext());
Log.d("androidos_analysis", "getApplication()       ——> " + getApplication());

완전히 아직 안드로이드 개발을하는 방법을 알고하지 않습니다 결국 어떤 상황을 이해하도록 기사?

우리는 이해하기 어려운 일이 아니다,이 두 결과가 동일 반환 찾을 수 있습니다

활동 #의 getApplication

/** Return the application that owns this activity. */
   public final Application getApplication() {
       return mApplication;
   }

사실, 두 가지의 응용 프로그램 getApplication 반환이 동일하다. 그러나 모든 반환 응용 프로그램, 안드로이드 왜 이러한 두 가지 방법의 존재? 이 문제의 범위, 우리는 getApplication가 활동하고 서비스 범위 사용하는 방법을 찾을 수 있습니다 포함한다, 그러나 우리는 우리가 getApplicationContext의 응용 프로그램을 얻기 위해 사용할 수있는 경우에 다른 곳에서이 방법을 사용할 수 없습니다. 어떤에서 상황은 무엇입니까? 예를 들어 : 브로드 캐스트 리시버 우리는이 방법을 얻기 위해 우리가 할 수있는 수신기 적용 사례에 싶어 :

public class MyReceiver extends BroadcastReceiver {  
    @Override  
    public void onReceive(Context context, Intent intent) { 
        MyApplication myApp = (MyApplication) context.getApplicationContext();  
        //...
    }  
}

위의 내용은 상황에 내용의 일부입니다.

마지막으로, 프로그래머, 내용 지식을 배우고, 오직 자신을 향상 제거 할 너무 많은 기술적, 환경 적 위해가 항상 우리는 환경에 우리에게 적응할 수있는 환경을하지 적응하기!

여기에 세트 수십 관련된 상기 기술 시스템 다이어그램 부착 질문 십구년 텐센트, 헤드 라인, 알리, 미국 그룹과 다른 회사에 직면 기술은 마무리 지점 비디오 및 PDF (사실, 예상보다 많은 시간을 보내는)이되었다, 를 포함하여 많은 세부 사항 + 지식 상황을 사진의 형태로 여기 때문에 공간 제한의 것은, 당신에게 그것의 일부를 표시합니다.

나는 당신에게 수확을 많이 가져올 것으로 예상 :

완전히 아직 안드로이드 개발을하는 방법을 알고하지 않습니다 결국 어떤 상황을 이해하도록 기사?

[위의 HD 뇌도, 저를 추가 할 수 있습니다 [지원] PDF 기술 아키텍처는 WX : X1524478394 무료로 이용할 수

때 쉽게 프로그래머, 좋은 프로그래머가 수석 건축가로 차에서 수석 프로그래머, 건축가에 주니어 프로그래머 배울 필요가있을 때, 또는 기술 관리자의 관리, 기술 이사에 각 단계에 우리는 서로 다른 기능이 필요합니다. 초기 직장 및 용량 건물에 동료를 던져하기 위해, 자신의 경력 방향을 결정합니다.

추천

출처blog.51cto.com/14332859/2455749