成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

二、AndroidNDK開發(fā)---從HelloWord學(xué)起-創(chuàng)新互聯(lián)

一 、NDK目錄簡單介紹

    在進(jìn)行NDK開發(fā)之前,我們有必須熟悉一下NDK目錄下包含哪些東西,以及這些東西對開發(fā)來說有什么作用?那么現(xiàn)在打開NDK的解壓目錄,查看一下解壓目錄下的文件:

1)samples目錄。這個目錄包含了Google為NDK開發(fā)撰寫的一些小例子,包括本地JNI開發(fā),圖片處理,多個庫文件開發(fā)等等,這些例子雖小但面面俱到,能看懂samples目錄下的小例子程序,那么對于NDK開發(fā)來說,就很好應(yīng)付了。

站在用戶的角度思考問題,與客戶深入溝通,找到豐滿網(wǎng)站設(shè)計與豐滿網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、主機(jī)域名、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋豐滿地區(qū)。

2)docs目錄。這個目錄下存放的都是Google給開發(fā)者提供的文檔,指導(dǎo)開發(fā)者怎樣在Android環(huán)境下進(jìn)行NDK開發(fā),這個非常重要。

3)sources目錄。由于Android是開源操作系統(tǒng),作為Android的一部分的NDK,同樣也是開源的,這個目錄下存放的是NDK源碼。

4)platforms目錄。里面存放的是當(dāng)前ndk版本所支持的所有android平臺的版本,做NDK開發(fā)的C代碼也是可以指定由某個特定版本平臺下編譯,該platforms目錄下存放的是不同版本所包含的C的庫文件和頭文件,不同版本有些微小的變化。

5)prebuilt目錄。這是提供給在Windows下開發(fā)ndk程序的一些工具集。

6)build目錄。里面存放大量的Linux編程腳本和Windows下的批處理文件,用來完成ndk開發(fā)中的交叉編譯。

二、具體開發(fā)

1,NDK開發(fā)步驟

    首先,我先列出NDK開發(fā)的簡單步驟,然后再以此為大綱,用一個Hello World的實(shí)例講述一下NDK開發(fā):

(1)創(chuàng)建一個android工程

(2)JAVA代碼中寫聲明native 方法 public native String helloFromJNI();

(3)創(chuàng)建jni目錄,編寫c代碼,方法名字要對應(yīng)在c代碼中導(dǎo)入jni.h頭文件

(4)編寫Android.mk文件

(5)Ndk編譯生成動態(tài)庫

(6)Java代碼load 動態(tài)庫.調(diào)用native代碼

2,NDK開發(fā)具體實(shí)踐

   下面就按照上述的步驟建立一個HelloWorld小案例來一步一步實(shí)現(xiàn)NDK開發(fā)

2.1,創(chuàng)建一個Android工程,并且在Java代碼中聲明一個native方法:
package com.example.ndkdemo01;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
static{
        System.loadLibrary("Hello");  //System.loadLibrary(String 文件名);是用來加載動態(tài)庫的方法,其中參數(shù)類型是字符串,參數(shù)是Android.mk文件中LOCAL_MODULE定義的名稱。
    }
private Button bt_click;
public native String javaFromJNI();    //聲明native方法
    @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub   super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt_click= (Button) this.findViewById(R.id.bt_click);
        bt_click.setOnClickListener(new OnClickListener() {
            
            @Override
public void onClick(View v) {
// TODO Auto-generated method stub                 Toast.makeText(MainActivity.this, javaFromJNI(),  
                            Toast.LENGTH_SHORT).show();  
            }
        });
    }

}
2.2,創(chuàng)建jni目錄,編寫Hello.c文件。
  先來說一下JNI代碼的簡單格式:方法簽名規(guī)則:返回值類型 Java_包名_類名_native方法名(JNIEnv* env, jobject obj)
 1) Java: 表示被Java調(diào)用。 包名:表示package的名稱(com_example_ndkdemo01),其中的"."被下劃線替代。     MainActivity:申明調(diào)用函數(shù)的類名。   javaFromJNI:申明的函數(shù)名。 2)怪異的返回值,在NDK中,不管是從Java傳過來的傳遞值,還是傳回Java的返回值,都是專門的參數(shù)(比如java中的string對應(yīng)ndk的jstring,int[]對應(yīng)jintarray,具體可參見jni.h)。

 3)多出來的傳遞參數(shù),JNIEnv* env和jobject thiz是底層函數(shù),必須要帶的參數(shù)。env開發(fā)者利用此參數(shù)做查詢和傳化數(shù)據(jù)類型(比如將jintarray轉(zhuǎn)換成int數(shù)組,在以后的章節(jié)中會詳細(xì)說明)。thiz表示這個調(diào)用這個函數(shù)的類對象,本文中就是MainActivity的對象。

#include<stdio.h>
#include<jni.h>


jstring Java_com_example_ndkdemo01_MainActivity_javaFromJNI(JNIEnv* env, jobject obj) {


return (*(*env)).NewStringUTF(env, "hello jni!");

}
3,編寫Android.mk文件和Application.mk

3.1 這個Android.mk文件怎么寫呢?這時候我們得打開NDK的文檔來看看了,位置E:/NDK/android-ndk-r10d/docs/Start_Here.html,找到

好,我們就先在jni目錄下創(chuàng)建一個Android.mk的文件,將上面的這段話復(fù)制粘貼進(jìn)去,將LOCAL_MODULE和LOCAL_SRC_FILES修改成我們自己寫成的C文件的名稱:

 LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE    := Hello
    LOCAL_SRC_FILES := Hello.c
 
    include $(BUILD_SHARED_LIBRARY)

 3.2 Application.mk文件的目的是描述在你的應(yīng)用程序中所需要的模塊(即動態(tài)庫或靜態(tài)庫)。

    Application.mk文件通常被放置在 $PROJECT/jni/Application.mk下,$PROJECT指的是您的項目。

    要將CC++代碼編譯為SO文件,光有Android.mk文件還不行,還需要一個Application.mk文件。

    

     

 3.3 NDK程序生成支持多種CPU架構(gòu)的SO包

   在我們android NDK項目的根目錄下面有一個libs文件夾,如下圖所示,這個文件夾下面有下面七個文件夾:arm64-v8a,armeabi ,armeabi-v7a,   mips, mips64,x86 ,x86_64。我們的c代碼編譯成SO庫就會放在這七個文件夾中的一個或多個中。那么這些文件夾中的SO文件有什么區(qū)別? arm64-v8a,armeabi ,armeabi-v7a,   mips, mips64,x86 ,x86_64是表示七種不同的cpu的架構(gòu),我們知道一般的手機(jī)或平板都是用arm的cpu,不同的cpu的特性不一樣,armeabi就是針對普通的或舊的arm v5 cpu,armeabi-v7a是針對有浮點(diǎn)運(yùn)算或高級擴(kuò)展功能的arm v7 cpu。應(yīng)用程序二進(jìn)制接口(Application Binary Interface)定義了二進(jìn)制文件(尤其是.so文件)如何運(yùn)行在相應(yīng)的系統(tǒng)平臺上,從使用的指令集,內(nèi)存對齊到可用的系統(tǒng)函數(shù)庫。在Android系統(tǒng)上,每一個CPU架構(gòu)對應(yīng)一個ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。

為每個支持的CPU架構(gòu)提供對應(yīng)的.so文件

  • 你應(yīng)該盡可能的提供專為每個ABI優(yōu)化過的.so文件,但要么全部支持,要么都不支持:你不應(yīng)該混合著使用。你應(yīng)該為每個ABI目錄提供對應(yīng)的.so文件。
  • 當(dāng)一個應(yīng)用安裝在設(shè)備上,只有該設(shè)備支持的CPU架構(gòu)對應(yīng)的.so文件會被安裝。在x86設(shè)備上,libs/x86目錄中如果存在.so文件的話,會被安裝,如果不存在,則會選擇armeabi-v7a中的.so文件,如果也不存在,則選擇armeabi目錄中的.so文件(因?yàn)閤86設(shè)備也支持armeabi-v7a和armeabi)。

    

   NDK開發(fā)中,如何編譯生成arm64-v8a,armeabi ,armeabi-v7a, mips, mips64,x86 ,x86_64七個文件夾下面的.so文件,可以在Application.mk里可以配置以下宏指定ABI生成機(jī)器代碼:

TARGET_CPU_API := all
APP_ABI := all
或者是
TARGET_CPU_API :=  armeabi armeabi-v7a x86 x86_64 arm64-v8a mips mips64
APP_ABI := armeabi armeabi-v7a x86 x86_64 arm64-v8a mips mips64

   默認(rèn)情況下,NDK的編譯系統(tǒng)根據(jù) "armeabi" ABI生成機(jī)器代碼??梢允褂肁PP_ABI 來選擇一個不同的ABI。

    比如:為了在ARMv7的設(shè)備上支持硬件FPU指令??梢允褂?nbsp;APP_ABI := armeabi-v7a

    或者為了支持IA-32指令集,可以使用     APP_ABI := x86

   或者為了同時支持這三種,可以使用      APP_ABI := armeabi armeabi-v7a x86

   或者有時候可能只需要兼容幾種cpu類型,則“TARGET_CPU_API :=” 和 “APP_ABI :=”隨便指定上面六種中任意一種。

   程序中可能會出現(xiàn)下面類似的錯誤,主要是由于沒有生成對應(yīng)支持CPU類型的SO文件

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/cn.com.chinatelecom.account-1/base.apk"],nativeLibraryDirectories=[/data/app/cn.com.chinatelecom.account-1/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "libFeedbackUtils.so"

4,ndk編譯生成動態(tài)庫

在eclipse中點(diǎn)擊項目,右擊->>Android Tools->>Add Native Support... 。隨后會有一個對話框彈出,在輸入框里輸入模塊名稱??梢钥吹骄幾g通過了,下面刷新一下工程,就可以看到工程libs目錄下多了個libHello.so的文件,這個就是Android認(rèn)識的動態(tài)庫了。

5,Java代碼load 動態(tài)庫.調(diào)用native代碼

編譯出來這個libHello.so文件后,就需要在Java代碼中加載這個.so的庫文件了,代碼很簡單,然后Toast一下看看效果:

System.loadLibrary(String 文件名);是用來加載動態(tài)庫的方法,其中參數(shù)類型是字符串,參數(shù)是Android.mk文件中LOCAL_MODULE定義的名稱。

參考博客 http://blog.csdn.net/allen315410/article/details/41805719 和http://www.cnblogs.com/yaozhongxiao/archive/2012/03/06/2381586.html和http://www.jianshu.com/p/cb05698a1968?from=timeline&isappinstalled=0

本文標(biāo)題:二、AndroidNDK開發(fā)---從HelloWord學(xué)起-創(chuàng)新互聯(lián)
文章路徑:http://jinyejixie.com/article46/gpjhg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣Google、網(wǎng)站策劃、網(wǎng)站導(dǎo)航靜態(tài)網(wǎng)站、網(wǎng)頁設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營
莆田市| 平塘县| 岑巩县| 姚安县| 紫云| 昭觉县| 宜兰县| 双峰县| 德钦县| 海丰县| 陈巴尔虎旗| 任丘市| 英山县| 南平市| 廊坊市| 盘锦市| 虞城县| 衡山县| 昌江| 郎溪县| 丹棱县| 乌鲁木齐市| 抚州市| 金乡县| 杭锦后旗| 通许县| 福建省| 庆元县| 石楼县| 寿阳县| 彩票| 盐津县| 夏邑县| 阿拉善右旗| 封丘县| 通辽市| 聂荣县| 和平县| 晋中市| 盐源县| 清水河县|