テンセントのインタビューは、Android追体験知識を紹介:BindServiceは、プロキシが同期または非同期で取得しますか?

テンセントのインタビューは、Android追体験知識を紹介:BindServiceは、プロキシが同期または非同期で取得しますか?

bindServiceでのAndroidのは、それがどういう意味、非同期プロセスのですか?

使用bindServiceは、単にバインダープロキシサービスを取得したいのですが、代理取得タイミングがエンドbindService制御によって開始されなかったが、bindService後と言うことですサービスの終了によって制御され、APPは一方で、すぐにプロキシエンドを取得することはありませんサービスは、次のように通知APPの終了を待つために、特定のプロセスを簡略化することが可能です。

  • APP bindServiceは、登録を介して第1のAMSを終了するには、このようなサービスを結合するそれらの必要性を説明するために、および配信アドレスを残します
  • APPは戻ってきて、他のことをし続けるために、それが非ブロッキングとして見ることができます
  • AMSは、サービス終了通知サービスを開始します
  • サービスが開始され、AMSブートさを知らせます
  • AMSアドレス通知APP APPの端の端面を離れる前にキャッチし、プロキシのプロキシAPPの終わりに渡されます

コードをより直接的に見て

    void test(){
        bindService(intent, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
               iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
               Log.v(TAG, "onServiceConnected..." );
            }
           @Override
            public void onServiceDisconnected(ComponentName componentName) {
           }
        }, Context.BIND_AUTO_CREATE);
        Log.v(TAG, "end..." );
    }

どのようにプロセスでBindService、上記のログコードは一種のすべきですか?bindServiceが同期プロセスである場合は、次のようにログは次のようになります。

TAG  onServiceConnected ...
TAG  end ...

しかし、それは非同期プロセスは、以下の実際のログであるため、

TAG  end ...    
TAG  onServiceConnected ...

bindService APPは、ソースコードからサポートすることができ、クライアントがプロキシを取得するのを待っているが、直接返さブロックしていないこと、ActivityManagerNativeを見に直接スキップ

public int bindService(IApplicationThread caller, IBinder token,
        Intent service, String resolvedType, IServiceConnection connection,
        int flags, int userId) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(caller != null ? caller.asBinder() : null);
    data.writeStrongBinder(token);
    service.writeToParcel(data, 0);
    data.writeString(resolvedType);
    data.writeStrongBinder(connection.asBinder());
    data.writeInt(flags);
    data.writeInt(userId);
    <!--阻塞等待-->
    mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
    reply.readException();
    int res = reply.readInt();
    data.recycle();
    reply.recycle();
    return res;
}

mRemote.transact(BIND_SERVICE_TRANSACTION、データ、返信、0)は実際にAMS BIND_SERVICE_TRANSACTION要求の実現を待って、APPは、呼び出し元のスレッドのブロックを終了させるんが、AMSは、この要求の実現に戻る前に、サービスを目覚めさせていない、それは、それ以前の時間を返し、ルックActivityManagerService、

public int bindService(IApplicationThread caller, IBinder token,
        Intent service, String resolvedType,
        IServiceConnection connection, int flags, int userId) {
    ...
    synchronized(this) {
        return mServices.bindServiceLocked(caller, token, service, resolvedType,
                connection, flags, userId);
    }
}

ActivityManagerServiceダイレクトコール機能bindServiceLocked ActiveServices、ここではサービス、APP-側スレッドを結合要求は、まだプロセスが開始されましたが、サービスサービスを開始しないで、その後、bindServiceLocked-> realStartServiceLockedに、さらに通話をActiveServicesと仮定して、AMSサーバ戻りを待ってブロックされていますここで面白いサービスを開始します。

 private final void realStartServiceLocked(ServiceRecord r,
            Proce***ecord app) throws RemoteException {
        ...
        <!--请求Service端启动Service-->
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
        ...
        <!--请求绑定Service-->
        requestServiceBindingsLocked(r);

app.thread.scheduleCreateServiceバインダー通信プロセスであり、彼が実際にApplicationThreadサービスにおける非同期リクエストActivityThreadをAMSされ、システムのサービス要求クライアントのローカルサービスは、一般的に非同期です。

// 插入消息,等待主线程执行
public final void scheduleCreateService(IBinder token,
        ServiceInfo info, CompatibilityInfo compatInfo) {
    CreateServiceData s = new CreateServiceData();
    s.token = token;
    s.info = info;
    s.compatInfo = compatInfo;
    <!--向Loop的MessagerQueue插入一条消息就返回-->
    queueOrSendMessage(H.CREATE_SERVICE, s);
}

しかし、この要求は直接直接リターン上のメッセージのスレッドサービスActivityThreadの端部に挿入されていますが、要求が実行されるまで、AMSは、いくつかのタスクを完了するために、クライアントのために、非常に頻繁に決して古い待機を使用しているため、クライアントへのAMSのエンドので、待つことはありませんでした、直接サービスが作成されていない実際には、この時間リターンをコマンドを送信して、あること、要求は半分しか実行しないも、onServiceConnected完了したときにそれを強制するためにonServiceConnectedされますか?app.thread.scheduleCreateService APPの端が最初のメッセージに挿入され、バインド処理するために、実際にはrequestServiceBindingsLockedサービス、2番目のメッセージを作成するために使用されます

 private final boolean requestServiceBindingLocked(ServiceRecord r,
            IntentBindRecord i, boolean rebind) {
                ...
           <!-- 第二个消息,请求处理绑定-->
            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);

2番目のメッセージは、いくつかの結合要件に対処するために、2番目のメッセージは最初のメッセージの後に行われなければならないことをAndroidのHanlderメッセージハンドリング機構保証します

 public final void scheduleBindService(IBinder token, Intent intent,
        boolean rebind) {
    BindServiceData s = new BindServiceData();
    s.token = token;
    s.intent = intent;
    s.rebind = rebind;
    queueOrSendMessage(H.BIND_SERVICE, s);
}      

以上の2件のメッセージが挿入され、AMSの終わりが目覚め、それが最初のメッセージの処理未知の非同期プロセス、サービス側だったので、その後、再び目覚めるbindService端部は前ブロックされたが、この時間は、サービスを作成する必要はありません後これは、サービスを作成し、

 private void handleCreateService(CreateServiceData data) {
    ...
    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = (Service) cl.loadClass(data.info.name).newInstance();
   ...

2番目のメッセージの実装は、それがAMSにpublishServiceを要求しますときに、実際には、配布エージェントの終了前にAPPに要求することができ、サービスが開始され、AMSを教えてください。

 private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (s != null) {
       try {
        data.intent.setExtrasClassLoader(s.getClassLoader());
        try {
            if (!data.rebind) {
                IBinder binder = s.onBind(data.intent);
                ActivityManagerNative.getDefault().publishService(
                        data.token, data.intent, binder);
            ...                       

クライアントがpublishService AMSメッセージを受信した後、通知がプロキシバインダーサービス・エージェントを通過する間に、APP、APPの終わりに送信され、したがって、バインダーによりonServiceConnectedコールバック関数を終了します

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    ...
     try {
    <!--通过binder 回到APP端的onServiceConnected--> 
        c.conn.connected(r.name, service);
    } catch (Exception e) {

ここでは、バックと呼ばれるonServiceConnected、しかし、それをサービスが実行され2つのメッセージを終了する必要がある場合の、保証はありません、特別な理由おそらくでは、と、2件のメッセージが実行されることはありませんので、それがバックonServiceConnectedと呼ばれることはありませんこれらのメッセージは、それらの2が実行されているブロックされていない、と次のように単純なプロセスがある場合ので、これは、AMSおよびその他の問題APPの終わりには影響しません。

テンセントのインタビューは、Android追体験知識を紹介:BindServiceは、プロキシが同期または非同期で取得しますか?

最後に、実際STARTSERVICEは非同期です。

文末

あなたが理解する必要がありますだけでなく、非常によくそれを表現できるようにするには、インタビュアーがご理解を認識できるようにいくつかのものは、例えば、ハンドラメカニズムのために、このインタビューは、質問をされるでしょう。いくつかの不明な点は、おそらくライブ唯一の実用的な仕事の中でのインタビューで、あなたはそれを使用しませんでしたが、あなたはそれが何であるかを知っています。

プログラマのために、コンテンツの知識を学ぶために、あまりにも多くの技術があり、唯一の自分自身を向上させる排除される環境順序ではない、常に私たちは環境に適応するために、いない環境では、私たちに適応します!

ここでのセットの数十に関連した上記技術的システム図添付の質問は、19年テンセント、見出し、アリ、米国のグループと他の企業が直面している技術は、終点のビデオとPDF(実際には、予想以上に多くの時間を費やす)となっており、含む知識のコンテキスト+多くの詳細ここではあなたにそれの一部を表示する絵の形で、紙面の都合で、。

私はそれがあなたの収穫の多くをもたらすと信じて:

テンセントのインタビューは、Android追体験知識を紹介:BindServiceは、プロキシが同期または非同期で取得しますか?

[上記のHD脳図]、および私を追加することができ、[サポート] PDF技術アーキテクチャは、WX:X1524478394の無料アクセスを

ときに簡単にプログラマ、優れたプログラマがシニアアーキテクトへのプライマリから上級プログラマー、建築家にジュニアプログラマから学ぶ必要があるとき、または技術的な管理から管理、テクニカルディレクターの各段階に私たちは、さまざまな機能を持っている必要があります。初期の研究では、キャパシティビルディングで仲間を投げるためには、自分のキャリアの方向性を決定します。

  • あなたは今のレベルを学ぶために続けなければならないかとノースープ、他の人が楽に見えるかどうかは、実際には、非常に強力なを取った、これらの4つの単語が私のアドバイスです!
  • 私たちは非常に困難であるため、私たちは値する、私たちが望むものを得るだろう、人生のあらゆる努力がITエンジニアことを願っています。

おすすめ

転載: blog.51cto.com/14332859/2455399