1. 程式人生 > >Android JNI基礎篇(一)

Android JNI基礎篇(一)

Android JNI基礎篇

前言

JNI學習其實並不難,在這裡,我將引導大家學習JNI的基礎知識,認真學完本教程,你將更加堅信我說的話。來吧,我們一起學習!

JNI基礎

JNI是什麼?

JNI的全稱就是Java Native Interface,顧名思義,就是Java和C/C++相互通訊的介面,就好比買賣房子都需要找中介一樣,這裡的JNI就是Java和C/C++通訊的中介,一箇中間人。

JNI標頭檔案

JNI開發前提是要引入jni.h標頭檔案,這個檔案Android NDK目錄下面

示例如下:

#include<jni.h>

怎麼載入so庫?

Android提供了3個實用的函式用來載入JNI庫,分別是System.loadLibrary(libname),Runtime.getRuntime().loadLibrary(libname),以及Runtime.getRuntime().load(libFilePath)。

loadLibrary函式載入

用System.loadLibrary(libname)和Runtime.getRuntime().loadLibrary(libname)這兩個函式載入so庫,不需要指定so庫的路徑,Android會預設從系統的共享庫目錄裡面去查詢,Android的共享庫目錄就是vendor/lib和system/lib,如果在共享庫路徑裡面找到指定名字的so庫,就會立即載入這個so庫,所以我們給so庫起名的時候要儘量避免和Android共享庫裡面的so庫同名。如果在共享庫目錄裡面查詢不到,就會在APP的安裝目錄裡面查詢APP的私有so庫,如果查詢到,會立即載入這個so庫。

load函式載入

Runtime.getRuntime().load(libFilePath)用這個函式載入so庫,需要指定完整的so庫路徑,優點是載入速度快,並且不會載入錯誤的so庫,缺點就是需要指定完整的so庫路徑,有時候並不方便,大家常用的載入so庫的方式還是用loadLibrary函式來載入。

載入so庫示例

static {
    System.loadLibrary("native-lib");
    //用這種方式載入so庫和System.loadLibrary函式載入so庫的效果是一樣的
    //Runtime.getRuntime().loadLibrary("native-lib");
    
//String soLibFilePath;     //用這種方式載入so庫需要指定完整的so庫路徑     //Runtime.getRuntime().load(soLibFilePath);
}

Android Studio so庫配置

Android Studio通過CMakeLists.txt檔案配置需要生成的so庫,下面詳細給大家介紹一下這個CMakeLists.txt檔案如何配置。

Android Studio通過cmake命令來生成so庫。

CMakeLists.txt檔案配置詳解

add_library

add_library函式用來配置要生成的so庫的基本資訊,比如庫的名字,要生成的so庫是靜態的還是共享的,so庫的C/C++原始檔列表

示例如下:

add_library( native-lib
             SHARED
             src/main/cpp/native-lib.cpp
             src/main/cpp/native-lib2.cpp
             src/main/cpp/native-lib3.cpp)

第一個引數是so庫的名字

第二個引數是要生成的so庫的型別,靜態so庫是STATIC,共享so庫是SHARED

第三個引數是C/C++原始檔,可以包括多個原始檔

find_library

find_library函式用來從NDK目錄下面查詢特定的so庫

示例如下:

find_library( log-lib
              log )

第一個引數是我們給要查詢的so庫起的名字,名字可以隨便寫

第二個引數是要查詢的so庫的名字,這個名字是從真實的so庫的名字去掉字首和字尾後的名字,比如liblog.so這個so庫的名字就是log

target_link_libraries

target_link_libraries函式用來把要生成的so庫和依賴的其它so庫進行連結,生成我們需要的so庫檔案

示例如下:

target_link_libraries( native-lib
                       ${log-lib} )

第一個引數是我們要生成的so庫的名字去掉字首和字尾後的名字,在這個例子中,要生成的真實的so庫的名字是libnative-lib.so

第二個引數是連結我們用find_library函式定義的查詢的依賴庫的名字log-lib,語法就是${依賴的庫的名字}

JavaJNI型別對照表

這裡詳細介紹一下Java型別和C/C++型別的對照關係,方便我們下面的學習,這一部分知識很基礎,也很重要。

JavaJNI基本型別對照表

Java的基本型別可以直接與C/C++的基本型別對映,因此Java的基本型別對開發人員是透明的。

Java型別

JNI型別

C/C++型別

大小

Boolean

jboolean

unsigned char

無符號8位

Byte

jbyte

char

有符號8位

Char

jchar

unsigned short

無符號16位

Short

jshort

short

有符號16位

Integer

jint

int

有符號32位

Long

jlong

long long

有符號64位

Float

jfloat

float

32位浮點值

Double

jdouble

double

64位雙精度浮點值

JavaJNI引用型別對照表

與Java基本型別不同,引用型別對開發人員是不透明的。Java類的內部資料結構並不直接向原生程式碼公開。也就是說原生C/C++程式碼並不能直接訪問Java程式碼的欄位和方法。

Java型別

C/C++型別

java.lang.Class

jclass

java.lang.Throwable

jthrowable

java.lang.String

jstring

java.lang.Object

jobject

java.util.Objects

jobjects

java.lang.Object[]

jobjectArray

Boolean[]

jbooleanArray

Byte[]

jbyteArray

Char[]

jcharArray

Short[]

jshortArray

int[]

jintArray

long[]

jlongArray

float[]

jfloatArray

double[]

jdoubleArray

通用陣列

jarray

說明任何Java陣列在JNI裡面都可以使用jarray來表示,比如Java的int[]陣列,用JNI可以表示為jintArray,也可以表示為jarray

JNI函式詳解

JNI字串相關的函式

C/C++字串轉JNI字串

NewString函式用來生成Unicode JNI字串

NewStringUTF函式用來生成UTF-8 JNI字串

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJString(JNIEnv* env, jobject thiz,jstring jstr) {
char *str="helloboy";
jstring jstr2=env->NewStringUTF(str);

const jchar *jchar2=env->GetStringChars(jstr,NULL);
size_t len=env->GetStringLength(jstr);
jstring jstr3=env->NewString(jchar2,len);
}

JNI字串轉C/C++字串

GetStringChars函式用來從jstring獲取Unicode C/C++字串

GetStringUTFChars函式用來從jstring獲取UTF-8 C/C++字串

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJString(JNIEnv* env, jobject thiz,jstring jstr) {
const char *str=env->GetStringUTFChars(jstr,NULL);
const jchar *jchar2=env->GetStringChars(jstr,NULL);
}

釋放JNI字串

ReleaseStringChars函式用來釋放Unicode C/C++字串

ReleaseStringUTFChars函式用來釋放UTF-8 C/C++字串

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJString(JNIEnv* env, jobject thiz,jstring jstr) {
const char *str=env->GetStringUTFChars(jstr,NULL);
env->ReleaseStringUTFChars(jstr,str);

const jchar *jchar2=env->GetStringChars(jstr,NULL);
env->ReleaseStringChars(jstr,jchar2);
}

JNI字串擷取

GetStringRegion函式用來擷取Unicode JNI字串

GetStringUTFRegion函式用來擷取UTF-8 JNI字串

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJString(JNIEnv* env, jobject thiz,jstring jstr) {
const char *str=env->GetStringUTFChars(jstr,NULL);
char *subStr=new char;
env->GetStringUTFRegion(jstr,0,3,subStr);
env->ReleaseStringUTFChars(jstr,str);

const jchar *jchar2=env->GetStringChars(jstr,NULL);
jchar *subJstr=new jchar;
env->GetStringRegion(jstr,0,3,subJstr);
env->ReleaseStringChars(jstr,jchar2);
}

獲取JNI字串的長度

GetStringLength用來獲取Unicode JNI字串的長度

GetStringUTFLength函式用來獲取UTF-8 JNI字串的長度

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJString(JNIEnv* env, jobject thiz,jstring jstr) {
jsize len=env->GetStringLength(jstr);
jsize len2=env->GetStringUTFLength(jstr);
}

JNI陣列相關的函式

JNI陣列相關的類

JNI類

備註

jbooleanArray

對應Java的boolean[]

jbyteArray

對應Java的byte[]

jcharArray

對應Java的char[]

jshortArray

對應Java的short[]

jintArray

對應Java的int[]

jlongArray

對應Java的long[]

jfloatArray

對應Java的float[]

jdoubleArray

對應Java的double[]

jobjectArray

對應Java的物件陣列object[]

JNI基本型別陣列

獲取JNI基本型別陣列元素

Get<Type>ArrayElements函式用來獲取基本型別JNI陣列的元素,這裡面的<Type>需要被替換成實際的型別,比如GetIntArrayElements,GetLongArrayElements等

示例程式碼如下:extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJIntArray(JNIEnv* env, jobject thiz,jintArray array) {
jint *intArray=env->GetIntArrayElements(array,NULL);
int len=env->GetArrayLength(array);
for(int i=0;i<len;i++){
jint item=intArray[i];
}
}

獲取JNI基本型別陣列的子陣列

Get<Type>ArrayRegion函式用來獲取JNI陣列的子陣列,這裡面的<Type>需要被替換成實際的型別,比如GetIntArrayRegion,GetLongArrayRegion等

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJIntArray(JNIEnv* env, jobject thiz,jintArray array) {
jint *subArray=new jint;
env->GetIntArrayRegion(array,0,3,subArray);
}

設定JNI基本型別陣列的子陣列

Set<Type>ArrayRegion函式用來獲取JNI基本型別陣列的子陣列,這裡面的<Type>需要被替換成實際的型別,比如SetIntArrayRegion,SetLongArrayRegion等

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJIntArray(JNIEnv* env, jobject thiz,jintArray array) {
jint *subArray=new jint;
env->GetIntArrayRegion(array,0,3,subArray);
env->SetIntArrayRegion(array,0,3,subArray);
}

JNI物件陣列

GetObjectArrayElement函式用來獲取JNI物件陣列元素

SetObjectArrayElement函式用來設定JNI物件陣列元素

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJObjectArray(JNIEnv* env, jobject thiz,jobjectArray array) {
int len=env->GetArrayLength(array);
for(int i=0;i<len;i++)
{
jobject item=env->GetObjectArrayElement(array,i);
}
}

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJStringArray(JNIEnv* env, jobject thiz,jobjectArray array) {
int len=env->GetArrayLength(array);
for(int i=0;i<len;i++)
{
jstring item=(jstring)env->GetObjectArrayElement(array,i);
}
}

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJObjectArray(JNIEnv* env, jobject thiz,jobjectArray array) {
jobject obj;
env->SetObjectArrayElement(array,1,obj);
}

獲取JNI陣列的長度

GetArrayLength用來獲取陣列的長度

示例如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJObjectArray(JNIEnv* env, jobject thiz,jobjectArray array) {
    int len=env->GetArrayLength(array);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testJIntArray(JNIEnv* env, jobject thiz,jintArray array) {
int len=env->GetArrayLength(array);
}

JNI NIO緩衝區相關的函式

使用NIO緩衝區可以在Java和JNI程式碼中共享大資料,效能比傳遞陣列要快很多,當Java和JNI需要傳遞大資料時,推薦使用NIO緩衝區的方式來傳遞。

NewDirectByteBuffer函式用來建立NIO緩衝區

GetDirectBufferAddress函式用來獲取NIO緩衝區的內容

GetDirectBufferCapacity函式用來獲取NIO緩衝區的大小

示例程式碼如下:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_testDirectBuffer(JNIEnv* env, jobject thiz) {
    const char *data="hello world";
    int len=strlen(data);
    jobject obj=env->NewDirectByteBuffer((void*)data,len);
    long capicity=env->GetDirectBufferCapacity(obj);
    char *data2=(char*)env->GetDirectBufferAddress(obj);
}

JNI訪問Java類的方法和欄位

Java型別簽名對映表

JNI獲取Java類的方法ID和欄位ID,都需要一個很重要的引數,就是Java類的方法和欄位的簽名,這個簽名需要通過下面的表來獲取,這個表很重要,建議大家一定要記住。

Java型別

簽名

Boolean

Z

Byte

B

Char

C

Short

S

Integer

I

Long

J

Float

F

Double

D

Void

V

任何Java類的全名

L任何Java類的全名;

比如Java String類對應的簽名是Ljava/lang/String;

type[]

type[

這個就是Java陣列的簽名,比如Java int[]的簽名是[I,Java long[]的簽名就是[J,Java String[]的簽名是 [Ljava/lang/String;

方法型別

(引數型別)返回值 型別,

比如Java方法void hello(String msg,String msg2)對應的簽名就是(Ljava/lang/String; Ljava/lang/String;)V

再比如Java方法String getNewName(String name)對應的簽名是(Ljava/lang/String;) Ljava/lang/String;

再比如Java方法long add(int a,int b)對應的簽名是(II)J

JNI訪問Java類方法相關的函式

JNI訪問Java類的例項方法

GetObjectClass函式用來獲取Java物件對應的類型別

GetMethodID函式用來獲取Java類例項方法的方法ID

Call<Type>Method函式用來呼叫Java類例項特定返回值的方法,比如CallVoidMethod,呼叫java沒有返回值的方法,CallLongMethod用來呼叫Java返回值為Long的方法,等等。

示例如下:

Java程式碼:

public native void callJavaHelloWorld2();
public void helloWorld2(String msg){
    Log.i("hello","hello world "+msg);
}
JNI程式碼:
extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_callJavaHelloWorld2(JNIEnv* env, jobject thiz) {
    jclass clazz=env->GetObjectClass(thiz);
    if(clazz==NULL) return;
    jmethodID helloWorld2_methodID=env->GetMethodID(clazz,"helloWorld2","(java/lang/String;)V");
    if(helloWorld2_methodID==NULL) return;
    const char *msg="hello world";
    jstring jmsg=env->NewStringUTF(msg);
    env->CallVoidMethod(thiz,helloWorld2_methodID,jmsg);
}
JNI訪問Java類的靜態方法

GetObjectClass函式用來獲取Java物件對應的類型別

GetStaticMethodID函式用來獲取Java類靜態方法的方法ID

CallStatic<Type>Method函式用來呼叫Java類特定返回值的靜態方法,比如CallStaticVoidMethod,呼叫java沒有返回值的靜態方法,CallStaticLongMethod用來呼叫Java返回值為Long的靜態方法,等等。

示例如下:

Java程式碼:

public native void callStaticJavaHelloWorld2();
public static void helloWorldStatic2(String msg){
    Log.i("hello","hello world static "+msg);
}

JNI程式碼:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_callStaticJavaHelloWorld2(JNIEnv* env, jobject thiz) {
    jclass clazz=env->GetObjectClass(thiz);
    if(clazz==NULL) return;
    jmethodID helloWorldStatic2_methodID=env->GetStaticMethodID(clazz,"helloWorldStatic2","(java/lang/String;)V");
    if(helloWorldStatic2_methodID==NULL) return;
    const char *msg="hello world";
    jstring jmsg=env->NewStringUTF(msg);
    env->CallStaticVoidMethod(clazz,helloWorldStatic2_methodID,msg);
}

JNI訪問Java類欄位相關的函式

JNI訪問Java類例項欄位

GetFieldID函式用來獲取Java欄位的欄位ID

Get<Type>Field用來獲取Java類欄位的值,比如用GetIntField函式獲取Java int型欄位的值,用GetLongField函式獲取Java long欄位的值,用GetObjectField函式獲取Java引用型別欄位的值

示例如下:

Java程式碼:

public class Person{
    public String name;
    public int age;
}

public native void getJavaObjectField(Person person);
private void test(){
    Person person=new Person();
    person.name="wubb";
    person.age=20;
    getJavaObjectField(person);
}

JNI程式碼:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_getJavaObjectField(JNIEnv* env, jobject thiz,jobject person) {
    jclass clazz=env->GetObjectClass(person);
    jfieldID name_fieldID=env->GetFieldID(clazz,"name","Ljava/lang/String;");
    jstring name=(jstring) env->GetObjectField(person,name_fieldID);

    jfieldID age_fieldID=env->GetFieldID(clazz,"age","I");
    jint age=env->GetIntField(person,age_fieldID);
}
JNI訪問Java類靜態欄位

GetStaticFieldID函式用來獲取Java靜態欄位的欄位ID

GetStatic<Type>Field用來獲取Java類靜態欄位的值,比如用GetStaticIntField函式獲取Java 靜態int型欄位的值,用GetStaticLongField函式獲取Java 靜態long欄位的值,用GetStaticObjectField函式獲取Java靜態引用型別欄位的值

示例如下:

Java程式碼:

public class Person {
    public String name;
    public int age;

    public static String name_static;
    public static int age_static;
}
public native void getJavaObjectStaticField(Person person);
private void test(){
    Person.name_static="wubb";
    Person.age_static=20;

    Person person=new Person();
    getJavaObjectStaticField(person);
}

JNI程式碼:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_getJavaObjectStaticField(JNIEnv* env, jobject thiz,jobject person) {
    jclass clazz=env->GetObjectClass(person);
    jfieldID name_fieldID=env->GetStaticFieldID(clazz,"name_static","Ljava/lang/String;");
    jstring name=(jstring) env->GetStaticObjectField(clazz,name_fieldID);

    jfieldID age_fieldID=env->GetStaticFieldID(clazz,"age_static","I");
    jint age=env->GetStaticIntField(clazz,age_fieldID);
}

JNI執行緒同步相關的函式

JNI可以使用Java物件進行執行緒同步

MonitorEnter函式用來鎖定Java物件

MonitorExit函式用來釋放Java物件鎖

示例如下:

Java程式碼:

jniLock(new Object());

JNI程式碼:

extern "C"
JNIEXPORT void JNICALL
Java_com_kgdwbb_jnistudy_MainActivity_jniLock(JNIEnv* env, jobject thiz,jobject obj) {
    env->MonitorEnter(obj);
    //do something
    env->MonitorExit(obj);
}

JNI異常相關的函式

JNI處理Java

相關推薦

Android JNI基礎

Android JNI基礎篇 前言 JNI學習其實並不難,在這裡,我將引導大家學習JNI的基礎知識,認真學完本教程,你將更加堅信我說的話。來吧,我們一起學習! JNI基礎 JNI是什麼? JNI的全稱就是Java Native Interface,顧名思義,就是Java和C

網絡基礎

分時 osi模型 郵件 高層 不用 電子設備 2msl 基於 三種 OSI模型的七層結構 1、物理層: 二進傳輸 為啟動、維護以及關閉物理鏈路定義了電氣規範、機械規範、過程規範、和功能規範。 2、數據鏈路層: 訪問介質: 定義如何格式化數據以便進行傳輸以及如何控制對網絡的訪

RecyclerView 全面使用及分析 - 基礎

一、RecyclerView 介紹 在 RecyclerView 出來之前,大家都在使用 ListView、GridView,當然 RecyclerView 出來之後,基本上都轉向了 RecyclerView,從名字上可以看出,它能夠實現view 的複用,同樣 ListView

numpy學習基礎

安裝好Numpy模組後,開始在jupyter上執行沒有問題,後來我開了一個pycharm,建立numpy.py這個檔案後,執行開始報如下錯誤:AttributeError: module ‘numpy‘ has no attribute ‘array‘  由於下載的模組名也為numpy.p

Java多執行緒-基礎

多執行緒---基礎篇,本文主要針對多執行緒的基礎進行復習,內容包括執行緒的理解,建立方式,Thread類函式理解; 1、執行緒的理解:OS系統角度:每個執行的程式都會被作業系統建立對應的程序(包括分配的資源、PCB等),程序是作業系統分配資源的基本單位(理解:程式執行需要空間,作業系統建立對應程序時

Java基礎--- 資料型別、函式、控制符

基本資料型別 1.整數型別: byte(1 位元組 ), short(2 位元組 ), int(4 位元組 ), long(8 位元組 ) 1位元組=8位,而每一個數的第一位為符號位,並且-0(負零)用-128表示,所以byte的範圍為:-2^(位元組8-1) --> 2^(位元組

nodejs之elasticsearch使用:基礎

nodejs之elasticsearch使用:基礎篇(一) 前言 程式碼 前言 本節只是嘗試使用nodejs中的elasticsearch模組實現elasticsearch在node環境下的基本增刪改查。 具體方法詳情

Java多執行緒之基礎

一、併發和並行 1.1 概念 1.2 比較 1.3 程序和執行緒 二、基礎概念 2.1 執

ActiveMQ·基礎

        JMS 叫做 Java 訊息服務(Java Message Service),是 Java 平臺上有關面向 MOM 的技術規範,旨在通過提供標準的產生、傳送、接收和處理訊息的 API 簡化企業應用的開發,類似於 JDBC 和關係型資料庫通訊方式的抽象。  

跟我一起學Mysql基礎

資料庫常用的術語 DB:資料庫(databases)儲存資料的“倉庫”。它儲存了一系列有組織的資料 DBMS:資料庫管理系統(Database Management System)。資料庫是通過DBMS

Spring Boot 入門之基礎

一、前言 Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新 Spring 應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。 本系列以快速入門為主,可當作工具小手冊閱讀

docker學習 基礎

備註:博主腦袋一熱,想做個軟體專案託管平臺,於是踏上了不歸路... 1. 前提知識    1.1 強制,熟悉linux命令和相關背景知識    1.2 建議,Git相關知識 2.docker簡介     2.1是什麼 &nb

python 基礎基本資料型別的宣告和定義

     最近對python比較感興趣:所以試著先學習了一下基礎部分;順便寫一下大致感受:至於python的環境變數以及開發工具IDE就不多做解釋; helloWord print("helloWord"); python 註釋:

【001】Python全棧日記-Python基礎

一、為什麼需要Python 如果你要用計算機做很多工作,最後你會發現有一些任務你更希望用自動化的方式進行處理。比如,你想要在大量的文字檔案中執行查詢/替換,或者以複雜的方式對大量的圖片進行重新命名和整理。也許你想要編寫一個小型的自定義資料庫、一個特殊的 GUI 應用程式或一個簡單的小遊戲。

Spring Boot 學習之基礎

該系列並非完全原創,官方文件、作者Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新 Spring 應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。一、環境搭建建立一個Maven專案,

樹莓派 3B 入手 基礎

              樹莓派3B 已經到手玩了好幾天了,之前一直用的飛思卡爾的arm9開發板,兩者相比真心覺得樹莓派真是太牛逼了。廢話少說,今天就是要把之前對樹莓派學習做一個總結; (一)、    拿到開發板第一件事就是想要讓開發板跑起來,因為官方樹莓派的開發板是裸機

[WebKit核心] JavaScript引擎深度解析--基礎位元組碼生成及語法樹的構建詳情分析

      看到HorkeyChen寫的文章《[WebKit] JavaScriptCore解析--基礎篇(三)從指令碼程式碼到JIT編譯的程式碼實現》,寫的很好,深受啟發。想補充一些Horkey沒有寫到的細節比如位元組碼是如何生成的等等,為此成文。       JSC對

Android效能優化——佈局優化

                                                 Android效能優化篇 題記: 不知道別人是怎麼學習的,我總是覺得我學習的效率很低,昨天發生了不愉快的事情後,我痛定思痛,反思了一下自己,還是總結不夠,也是工作中接觸的東西

SQL必知必會--基礎

    最近又把《SQL 必知必會》仔細翻了一遍,因此將基礎知識整理回顧,加深印象。 sql 結構化查詢語言(Structured  Query Language  的縮寫),用於訪問和處理資料庫; sql 不區分大小寫,處理時空格被忽略; 多條語句必須以分號(;)分隔

UEFI+GPT引導基礎:什麼是GPT,什麼是UEFI?

轉自:http://www.iruanmi.com/install-64bit-windows-7-on-a-pre-installed-win8-pc/ 其實關於UEFI的幾篇文章很早就寫下了,只是自己讀了一遍感覺很不滿意,就決定重寫。目的是想用最簡單直白的語言把內容