jni中的進程通信的另外一種實現方式

在adb shell中執行ps命令常看到後臺進程,這些後臺進程不少都是在JNI層建立的,並不是普通的Android進程,那麼問題來了,如何讓進程通信呢?shell


方式有不少種。api

1. 建立socket進行通信,「127.0.0.1」+ 特定的端口號。這種方式很經常使用。socket

2. 管道,父進程和子進程是能夠經過管道來讀寫數據的。這個比較經常使用。url

3. 直接寫入特定的文件,這也是本博文要介紹的一種實現,這個估計用的不多,可是在某些狀況下使用頗有意思,尤爲是對主進程來講,只須要寫入文件。code


Android是從Linux上修改過來的,Linux上很多api也是可以直接在Android上使用的,inotify就是其中一個,用於監控文件系統中的事件。當子進程監控特定的文件,父進程寫入該文件時,子進程是能獲取到該文件被修改的事件的,也就能直接讀取文件中的內容了。如下是代碼片斷進程

size_t readBytes = read(fileDescriptor, p_buf, EVENT_BUF_LEN);
int k = 0;
while (k < readBytes){
   struct inotify_event *event = ( struct inotify_event * )(p_buf + k);
   if (event->len > 0){
        kesyPrintf("event.name=%s\n", event->name);
   }

   // print mask
   kesyPrintf("mask=0x%x, wd=%d\n", event->mask, event->wd);
   
   ...
   
   if (event->wd == wdAccount){
        if (IN_CLOSE_WRITE & event->mask > 0){
             kesyPrintf("AccountInfo change detected!!!");
             
             // read account info
             FILE *f = fopen(gAccountPath, "r");
             if (f != NULL){
                  char buf[ANDROID_MAX_PATH];
                  if (NULL != fgets(buf, ANDROID_MAX_PATH, f)){
                       kesyPrintf("AccountInfo changed:");
                       kesyPrintf("%s", buf);
                       strcpy(gUrl, buf);
                  }
                  else{
                       kesyPrintf("failed to read url\n");
                       printerr();
                  }
                  fclose(f);
             }
             else{
                  kesyPrintf("failed to open file accountInfo\n");
             }
        }
        
        if (IN_DELETE_SELF & event->mask > 0){
             kesyPrintf("urlFoo is deleted");
        }
   }
   
   ...
   
   k += EVENT_SIZE + event->len;
}

inotify_rm_watch(fileDescriptor, wdAccount);
close(fileDescriptor);



-------歡迎吐槽事件

-----------by jacksonkeip

相關文章
相關標籤/搜索