1. 程式人生 > >Jni 兩種方法開啟底層檔案返回FD給Java

Jni 兩種方法開啟底層檔案返回FD給Java

開啟檔案

在底層open一個檔案時只是返回一個fd號,而Java開啟一個檔案用的是FileDescriptor來開啟一個檔案,如何在兩者之間建立一個聯絡呢?有兩種方法:

方法一:在jni層有提供一個API,jniCreateFileDescriptor(env, fd); 生成的是一個臨時變數,最終還是要通過NewObject建立一個物件才能return回去。在Android.mk裡還要加入這些庫,這些庫從系統裡的jni的Android.mk裡抄過來的,jniCreateFileDescriptor要用到的是哪個庫還有待研究。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17    jclass clazz = env->FindClass("android/os/ParcelFileDescriptor"); if(clazz == NULL){ XLOGE("Unable to find class android.os.ParcelFileDescriptor");  return -1; }    gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);    gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, 
"<init>""(Ljava/io/FileDescriptor;)V");  jobject fileDescriptor = jniCreateFileDescriptor(env, fd); if(fileDescriptor == NULL){ XLOGE("jniCreateFileDescriptor error"); return NULL; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);

Android.mk用到的庫

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 LOCAL_SHARED_LIBRARIES := \ libandroid_runtime \ libandroidfw \ libbinder \ libcutils \ liblog \ libhardware \ libhardware_legacy \ libnativehelper \ libutils \ libui \ libinput \ libinputservice \ libsensorservice \ libskia \ libgui \ libusbhost \ libsuspend \ libdl \ libEGL \ libGLESv2

方法二:

直接建立找到這個類,並呼叫這個物件的構建函式建立這個物件

1 2 3 4 5 6 7 8 /* Create a corresponding file descriptor */ { jclass cFileDescriptor = env->FindClass("java/io/FileDescriptor"); jmethodID iFileDescriptor = env->GetMethodID(cFileDescriptor, "<init>""()V"); jfieldID descriptorID = env->GetFieldID(cFileDescriptor, "descriptor""I"); mFileDescriptor = env->NewObject(cFileDescriptor, iFileDescriptor); env->SetIntField(mFileDescriptor, descriptorID, (jint)fd); }

關閉檔案

關閉檔案也有兩種檔案

一. 在開啟的時候把fd儲存為全域性變數,關閉的時候只要close(fd)。即可

二. 這是一個比較顯高階的方法,就是找到開啟這個檔案的類,然後在這裡類裡找到FileDescriptor變數,再找出該FileDescriptor物件裡的fd變數,關閉fd即可

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void closeFile(JNIEnv *env, jobject thiz){ //根據物件this獲取這個物件的類 jclass SerialPortClass = env->GetObjectClass(thiz); //找出FileDescriptor類 jclass FileDescriptorClass = env->FindClass( "java/io/FileDescriptor"); //在SerialPortClass這個類裡找出mFd這個變數的ID,這個變數的型別是FileDescriptor jfieldID mFdID = env->GetFieldID(SerialPortClass, "mFd","Ljava/io/FileDescriptor;"); //在FileDescriptor裡找出descriptor的ID,這是一個整型。就是我們用open開啟返回的那個fd jfieldID descriptorID = env->GetFieldID(FileDescriptorClass, "descriptor""I"); //根據上面找出來的mFd的ID,從在erialPortClass這個類裡找出mFd這個例項變數 jobject mFd = env->GetObjectField(thiz, mFdID); //根據上面找出來的mFd的例項變數,再從裡面這個類裡找出mFD例項變數裡的descriptor

相關推薦

Jni 方法開啟底層檔案返回FDJava

開啟檔案 在底層open一個檔案時只是返回一個fd號,而Java開啟一個檔案用的是FileDescriptor來開啟一個檔案,如何在兩者之間建立一個聯絡呢?有兩種方法: 方法一:在jni層有提供一個API,jniCreateFileDescriptor(env, fd

[LeetCode][14]Longest Common Prefix解析 演算法和底層原始碼的深入對比-Java實現

Q: Write a function to find the longest common prefix string amongst an array of strings. A: 這題的大概意思就是說給你一組字串找出其中最長的哪個通用的前綴出來。這個東西不難找,但是如

node伺服器中開啟html檔案方法

方法1:利用 Express 託管靜態檔案,詳情檢視這裡 方法2:使用fs模組提供的readFile方法開啟檔案,讓其以text/html的形式輸出。 程式碼: var express = req

eclipse開啟當前檔案所在資料夾的方法

很鬱悶,現在的MyEclipse越來越大,越來越慢,沒辦法,打算迴歸Eclipse的懷抱,還好現在的Eclipse有很多功能可以直接替代Myeclipse.:) 先寫一個最常用的開啟資料夾吧。以後的等我總結了並證實好用了再說;)  如果你經常需要在Eclipse裡開啟相

python開啟進程的方法

調用父類 結果 __init__ 當前 ini color pro print 一個 1.開啟進程的方法一 from multiprocessing import Process import time def work(name): #定義一個函數 print

SpringMVC中controller返回json數據的方法

rac new enter req imp 工具 response 返回 basepath SpringMVC中controller返回json數據的兩種方法 1.jsp的ajax請求: function getJson(){ $.ajax({ t

呼叫jni方法javah和RegisterNatives

前言: 呼叫jni的有兩種方法: 一種是通過javah 自動生成jni檔案 一種是載入類庫的時候,呼叫JNIEnv 指標的RegisterNatives方法註冊native方法 RegisterNatives方式有3種好處 1、jni種函式命名自由,不必像javah

方法刪除github遠端倉庫裡的檔案(不改變本地倉庫)

方法一(假如你要刪除的資料夾在你的本地倉庫也存在): 前提:假如你要刪除的資料夾在你的本地倉庫也存在,當然你也可以直接在github客戶端把本地倉庫更新一下,這樣你的本地倉庫裡就有你要刪除的檔案了,然後你在刪除,就到了下一步。 直接在本地倉庫刪除那個檔案,這個時候你的github客戶端會捕捉

初夏小談:C/C++防止標頭檔案被重複包含的方法及區別

防止標頭檔案被重複包含的兩種方式: 1.條件編譯的巨集 2.#pragma once 先來說說第一種: #ifndef __HEADNAME__H__ #define __HEADNAME__H__ //... //標頭檔案 #endif C/C++標準支援

pyspark 讀取csv檔案建立DataFrame的方法

pyspark 讀取csv檔案建立DataFrame的兩種方法 方法一:用pandas輔助 from pyspark import SparkContext from pyspark.sql import SQLContext import pandas as pd sc

Oracle備份歸檔日誌檔案方法比較

備份歸檔日誌方式有兩種:  1 單獨備份歸檔日誌:backup archivelog all  2 在執行備庫時一起備份歸檔日誌:backup database plus archivelog;  這兩種方式有什麼區別呢?  執行ba

C#讀寫txt檔案方法介紹

1.新增名稱空間   System.IO;   System.Text; 2.檔案的讀取   (1).使用FileStream類進行檔案的讀取,並將它轉換成char陣列,然後輸出。 byte[] byData = new byte[100]; c

ionic2 從子頁面返回帶引數的方法

1、使用 Modal 代替 NavController 的 push 方法,然後在子頁面通過 dismiss 方法關閉時可攜帶引數返回母頁面。 在母頁面中: getDetailNews(id) { let newsModal = this.modalCtrl.cr

Python檔案操作的方法 快速入門

python內建函式 1.試著向檔案中寫一句話 路徑:“C:/Users/thinkpad/Desktop/demo.txt” 開啟方式:寫(‘w’) # -*- encoding: UTF-8 -*- fp = open("C:/Users/thinkpad/

方法讓 Maya 載入使用Qt Designer 所建立的ui檔案

雖然我寫指令碼還不是很熟練但是總是在沒有UI的純程式碼下除錯真的很煩。選擇這個執行一下,再選擇這個執行一下,最後按順序選擇這幾個再執行一下。。。。。過了幾天自己好像都看不太懂了。還是學習一下UI的寫法吧。 maya建立UI可以自己純用程式碼來寫,也可以藉助一個叫Qt Des

頁面可返回到前一頁離開時的瀏覽位置方法

方法一:簡單粗暴返回前一頁  1 <a id="aa">News & Events</a> 2 3 4 <script> 5 $("#aa").click(function(){ 6 history.go(-1) 7 }) 8 <

STM32Fatfs遍歷檔案方法

//遍歷檔案 //path:路徑 //返回值:執行結果 u8 mf_scan_files(u8 * path) {     FRESULT res;     char *fn;   /* This function is assuming non-Unicode cfg. *

MySQL資料庫遠端訪問許可權如何開啟(方法)

在我們使用mysql資料庫時,有時我們的程式與資料庫不在同一機器上,這時我們需要遠端訪問資料庫。預設狀態下,mysql的使用者沒有遠端訪問的許可權。 下面介紹兩種方法,解決這一問題。 1、改表法 可能是你的帳號不允許從遠端登陸,只能在localhost。這個時候只要

Java專案打包成jar檔案方法

* Export generated class files and resources 表示只匯出生成的.class檔案和其他資原始檔 * Export all output folders for checked projects 表示匯出選中專案的所有資料夾 * Export java source f

Eclipse將引用了第三方jar包的Java專案打包成jar檔案方法

方案一:用Eclipse自帶的Export功能 步驟1:準備主清單檔案 “MANIFEST.MF”, 由於是打包引用了第三方jar包的Java專案,故需要自定義配置檔案MANIFEST.MF,在該專案下建立檔案MANIFEST.MF,內容如下: Manifest-Version: 1.0 Clas