乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Android 雙進程守護嘗試與分析

       風雪夜歸人_95 2015-03-26
             最近在做一個Android的項目,其包含一個消息推送的后臺服務。由于該服務可能會有重要的信息推送,因此并不希望當APP程序退出、APP程序被一鍵清理、APP被強制停止等用戶操作發(fā)生時,這個后臺服務也隨之被殺死。這個問題也就是所謂的“內(nèi)存永駐”。關(guān)于這個問題,網(wǎng)上有很多說法,如調(diào)用startforehand函數(shù)以提高service的優(yōu)先級、在service中創(chuàng)建一個不能被刪掉的notification(或者產(chǎn)生一個其他的與用戶界面交互的UI控件)、在service的onDestroy函數(shù)中重啟這個服務、修改onstartcommand函數(shù)的返回值等等。這些方法,筆者都一一試過,但都沒有效果。但是,我們可以看到市面上也確實存在一些App在一定的時間后可以自動重啟,說明仍然是存在方法可以完成這項任務的。筆者在網(wǎng)上看到了這篇文章 http:///a/jingxuanboke/2014/0622/354671.html,覺得還是有些道理的。于是照著這個原理去做了。
             這篇文章中介紹的方法涉及到Android的JNI編程,主要思想就是通過調(diào)用native函數(shù)創(chuàng)建一個子進程。父子進程相互監(jiān)聽,若子進程死去,父進程妥善處理后重新創(chuàng)建新的子進程;若父進程死去,子進程使用AM命令重啟父進程。這種思想唯一的缺陷就是如何保證父子進程不被同時殺死的情況。子進程能不能被殺死,只能用實驗來證明。
           首先筆者按照文章介紹的,整理了代碼,并將相關(guān)代碼植入到自己的項目中。
           步驟1)編寫Watcher類。它為上面的Java程序調(diào)用提供必要的接口,聲明需要native語言實現(xiàn)的的具體函數(shù)。native語言主要是指C/C++語言。上層的Java程序只需要創(chuàng)建一個Watcher類并調(diào)用它的createAppMonitor(String userId)函數(shù)即可。
       public class Watcher {
          private static final String PACKET = "com.example.dameonservice";
          private String mMonitoredService = "com.example.mqtt.MQTTSubscribeService";
          private volatile boolean bHeartBreak = false;
          private Context mContext;
          private boolean mRunning = true;
          
          public void createAppMonitor(String userId)
          {
              if(!createWatcher(userId))
              {
                  Log.e("Watcher", "<<Monitor created failed>>");
              }
          }
          
          public Watcher(Context context)
          {
              mContext = context;
          }
        
          /*創(chuàng)建一個監(jiān)視子進程
           *userId 當前進程的用戶ID,子進程重啟當前進程時需要用到當前進程的用戶ID
           *return  若子進程創(chuàng)建成功返回TRUE,否則返回FALSE
           */
          private native boolean createWatcher(String userId);
          
          /* 讓當前進程連接到監(jiān)視進程
           * return 連接成功返回TRUE,否則返回FALSE
           */
          private native boolean connectToMonitor();
          
          /*向監(jiān)視進程發(fā)送任意信息
           * msg 發(fā)給monitor的信息
           * return 實際發(fā)送的字節(jié)數(shù)
           */
          private native int sendMsgToMonitor(String msg);
          
          static
          {
              System.loadLibrary("monitor");   //這里要和后面的Android.mk中模塊名對應
          }
      }

      2)編譯上面的文件會在bin/classes 目錄下生成相對應的Watcher.class文件,通過DOs界面進入該bin/classes 目錄下,通過javah命令生成C/C++對應的頭文件。
      “javah 包名+類名”   得到以下頭文件:
       #include <jni.h>
      /* Header for class com_example_dameonservice_Watcher */

      #ifndef _Included_com_example_dameonservice_Watcher
      #define _Included_com_example_dameonservice_Watcher
      #ifdef __cplusplus
      extern "C" {
      #endif
      /*
       * Class:     com_example_dameonservice_Watcher
       * Method:    createWatcher
       * Signature: (Ljava/lang/String;)Z
       */
      JNIEXPORT jboolean JNICALL Java_com_example_dameonservice_Watcher_createWatcher
        (JNIEnv *, jobject, jstring);

      /*
       * Class:     com_example_dameonservice_Watcher
       * Method:    connectToMonitor
       * Signature: ()Z
       */
      JNIEXPORT jboolean JNICALL Java_com_example_dameonservice_Watcher_connectToMonitor
        (JNIEnv *, jobject);

      /*
       * Class:     com_example_dameonservice_Watcher
       * Method:    sendMsgToMonitor
       * Signature: (Ljava/lang/String;)I
       */
      JNIEXPORT jint JNICALL Java_com_example_dameonservice_Watcher_sendMsgToMonitor
        (JNIEnv *, jobject, jstring);

      #ifdef __cplusplus
      }
      #endif
      #endif


      3)創(chuàng)建JNI文件夾,將得到的頭文件移到該文件夾下,繼續(xù)在該文件夾下創(chuàng)建與上面得到的頭文件同名的C/C++文件,然后實現(xiàn)頭文件中提到的方法。(具體實現(xiàn)太多,這里就不再貼出來了)

      4)添加Android.mk文件。這個文件的格式基本是統(tǒng)一的。只需要修改LOCAL_MODULELOCAL_SRC_FILES兩處即可。如果你還有添加Log打印函數(shù),還要在這里添加 “LOCAL_LDLIBS := -lm -llog”。

      下面一張圖來說明整體的文件結(jié)構(gòu)分布:
       其中com_example_dameonservice_Watcher.c和com_example_dameonservice_Watcher.cpp內(nèi)容相同。process.cpp定義一些輔助類。

      實驗結(jié)果:
             這當然是大家最關(guān)心的。測試的手機選用的小米,感覺 小米在這一塊的優(yōu)化還是很不錯的,所以用它來試試。最終的測試結(jié)果是:被殺死的服務概率性地可以重啟成功,且失敗的概率更大。通過Log分析,不能重啟的時候是因為子進程也死掉了。截止到筆者寫下這篇文章,還沒有抓住其中的規(guī)律。一鍵清理和子進程的被殺死沒有絕對的對應關(guān)系。而且即使是在App運行的時候,也會發(fā)現(xiàn)子進程會被殺死,然后又被父進程重啟。子進程被殺死是重啟失敗的主要原因。但現(xiàn)在的現(xiàn)象無法確定子進程被殺死的確切原因,有一種可能是被系統(tǒng)殺死了,但這樣的不確定性太大,對效果也不能有很好的保證。
            雖然沒有完美解決問題,但至少比前面的辦法強很多,至少它也重啟成功過。這個方法感覺繼續(xù)優(yōu)化一下還是可以做好的。




        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多