亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android服務器怎么實現so文件調用

發布時間:2022-03-21 16:41:33 來源:億速云 閱讀:337 作者:iii 欄目:大數據

本文小編為大家詳細介紹“Android服務器怎么實現so文件調用”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Android服務器怎么實現so文件調用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

隨著 Android 移動安全的高速發展,不管是為了執行效率還是程序的安全性等,關鍵代碼下沉 native 層已成為基本操作。

native 層的開發就是通指的 JNI/NDK 開發,通過 JNI 可以實現 java 層和 native 層(主要是 C/C++ )的相互調用,native 層經編譯后產生 so 動態鏈接庫,so 文件具有可移植性廣,執行效率高,保密性強等優點。

那么問題來了,如何調用 so 文件顯得異常重要,當然你也可以直接分析 so 文件的偽代碼,利用強悍的編程功底直接模擬關鍵操作,但是我想對于普通人來說頭發還是比較重要的。

當前調用 so 文件的主流操作應該是:

1,基于 Unicorn 的各種實現(還在學習中,暫且不表)  

2,Android 服務器的搭建,在 App 內起 http 服務完成調用 so 的需求(當然前提是過了 so 的效驗等操作)

至于為什么選用 AndServer,好吧,不為什么,只是因為搜索到了它  

為什么結合 Service,在學習 Android 開發的時候了解到了 Service 的生命周期,個人理解用 Service 去創建 Http 服務比較好。

當然也有 Application 的簡單使用,因為在正式環境中,大多數 so 文件的邏輯中都有 context 的一些包名了,簽名了的效驗等,自定義 Application 的話獲取 context 傳參就好了。

libyemu.so 簡介

這是我編譯好的一個 so 文件,就是根據入參做下簡單的字符串拼接(以下是 native 層編譯前的 c 代碼)

extern "C"JNIEXPORT jstring JNICALLJava_com_fw_myapplication_ndktest_NdkTest_stringFromUTF(JNIEnv *env, jobject instance, jstring str_) {    jclass String_clazz = env->FindClass("java/lang/String");    jmethodID concat_methodID = env->GetMethodID(String_clazz, "concat", "(Ljava/lang/String;)Ljava/lang/String;");    jstring str = env->NewStringUTF("  from so --[NightTeam夜幕]");    jobject str1 = env->CallObjectMethod(str_, concat_methodID, str);    const char *chars = env->GetStringUTFChars((jstring)str1, 0);    return env->NewStringUTF(chars);}

這部分代碼還是有必要貼一下的,簡單的靜態注冊使用了反射的思想,反射在逆向中至關重要

接下來是 java 代碼,定義了 native 函數

package com.fw.myapplication.ndktest;public class NdkTest {    public static native String stringFromUTF(String str);    static {        System.loadLibrary("yemu");    }}

如果到這里有點懵逼的同學可能需要去補下 Android 開發基礎了

Android 項目測試 so

先說下我的環境,因為這個環境影響太大了  

1,AndroidStudio 3.4  

2,手機 Android 6 架構 armeabi-v7a  

打開 AndroidStudio 新建 project  

Android服務器怎么實現so文件調用cdn.nlark.com/yuque/0/2020/webp/97322/1607479407035-f0bfc349-9792-4b75-be4b-0b2c52f2cabc.webp?x-oss-process=image/watermark,type_d3F5LW1pY3JvaGVp,size_10,text_dGl0b2RhdGEuY29t,color_FFFFFF,shadow_50,t_80,g_se,x_10,y_10">

在 module 的 build 中加這么一句,然后 sync  

Android服務器怎么實現so文件調用

把編譯好的 so 文件復制到 libs 文件夾下(和剛才的 jniLibs.srcDirs 對應)  

Android服務器怎么實現so文件調用

把 so 對應的 java 代碼也 copy 過來,注意包名類名的一致性  

Android服務器怎么實現so文件調用

打開 activity_main.xml 文件為 TextView 添加 id  

Android服務器怎么實現so文件調用

打開 MainActiviy.java 開始編碼  

Android服務器怎么實現so文件調用

這兩行的意思就是,先從布局中找到對應 id 的 TextView,然后為其設置 Text(調用 native 函數的返回值)  

下面測試一下咱們的 so 調用情況  

Android服務器怎么實現so文件調用

可以看到咱們的 so 文件調用成功(這里咱們的 so 沒有效驗,只是測試 app 是否可以正常調用)

AndServer 代碼編寫

AndServer 官方文檔:https://yanzhenjie.com/AndServer/  

打開官方文檔,看看人家的入門介紹,新建 java 文件  

Android服務器怎么實現so文件調用

如圖經典 MVC 的 C 就寫好了,定義了一個 nightteam_sign 接口,請求方式為 get,請求參數為 sign,調用 native 函數,然后返回 json,但是這里我想利用 Application 獲取下 context 對象,取下包名,接下來自定義 Applictaion

package com.nightteam.httpso;import android.app.Application;public class MyApp extends Application {    private static MyApp myApp;    public static MyApp getInstance() {        return myApp;    }    @Override    public void onCreate() {        super.onCreate();        myApp = this;    }}

然后在 manifest 文件中指定要啟動的 Application  

Android服務器怎么實現so文件調用

然后修改 MyController.java 的代碼  

Android服務器怎么實現so文件調用

接下來把官方文檔-服務器的代碼 copy 下來  

導入一些包,修改部分代碼如下  

Android服務器怎么實現so文件調用

新版本的 AndServer.serverBuilder 已經需要傳遞 context 了,這里把網絡地址和端口號也修改為從構造參數中獲取,到這里 AndServer 的東西基本完了,實際上咱們就搭建一個調 so 的接口,并沒有過多的業務邏輯,所以代碼就是使用的最簡單的

Service 代碼編寫

咱們這里用按鈕的點擊事件啟動 Service,故在 activity_main.xml 中添加一個 button 并指定點擊事件  

Android服務器怎么實現so文件調用

Android服務器怎么實現so文件調用

接下來編寫自定義 Service 代碼

package com.nightteam.httpso.Service;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;import com.nightteam.httpso.ServerManager;import java.net.InetAddress;import java.net.UnknownHostException;public class MyService extends Service {    private static final String TAG = "NigthTeam";    @Override    public void onCreate() {        super.onCreate();        Log.d(TAG, "onCreate: MyService");        new Thread() {            @Override            public void run() {                super.run();                InetAddress inetAddress = null;                try {                    inetAddress = InetAddress.getByName("0.0.0.0");                    Log.d(TAG, "onCreate: " + inetAddress.getHostAddress());                    ServerManager serverManager = new ServerManager(getApplicationContext(), inetAddress, 8005);                    serverManager.startServer();                } catch (UnknownHostException e) {                    e.printStackTrace();                }            }        }.start();    }    @Override    public IBinder onBind(Intent intent) {        return null;    }}

打上了幾個 log,在子線程中啟動 AndServer 的服務(何時使用 UI 線程和子線程是 Android 基礎,這里就不贅述了)  

注意一下,這里從 0.0.0.0 獲取 inetAddress,可不要寫錯了,localhost 和 0.0.0.0 的區別請移步搜索引擎  

然后就是向 ServerManager 的構造函數傳遞 context,inetAddress,port 用來 new 對象,隨后開啟服務

最后注意檢查下 manifest 文件中 Service 的聲明  

Android服務器怎么實現so文件調用

開啟 Service,并獲取本機 ip

回到我們的 MainActivity.java 的 operate( button 的點擊事件)編寫啟動 Service 代碼

public void operate(View view) {        switch (view.getId()){            case R.id.id_bt_index:                //啟動服務:創建-->啟動-->銷毀                //如果服務已經創建了,后續重復啟動,操作的都是同一個服務,不會再重新創建了,除非你先銷毀它                Intent it1 = new Intent(this, MyService.class);                Log.d(TAG, "operate: button");                startService(it1);                ((Button) view).setText("服務已開啟");                break;        }    }

到這里我們的服務基本搭建好了,但是為了方便起見,我想把咱們的本機 ip 顯示在 App 上,這樣我們就不用去設置再查看了  

我在網上找到了一個獲取 ip 地址的一個工具類,源碼如下:

package com.nightteam.httpso;import java.net.InetAddress;import java.net.NetworkInterface;import java.net.SocketException;import java.util.Enumeration;import java.util.regex.Pattern;public class NetUtils {    private static final Pattern IPV4_PATTERN = Pattern.compile("^(" +            "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +            "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");    private static boolean isIPv4Address(String input) {        return IPV4_PATTERN.matcher(input).matches();    }    //獲取本機IP地址    public static InetAddress getLocalIPAddress() {        Enumeration<NetworkInterface> enumeration = null;        try {            enumeration = NetworkInterface.getNetworkInterfaces();        } catch (SocketException e) {            e.printStackTrace();        }        if (enumeration != null) {            while (enumeration.hasMoreElements()) {                NetworkInterface nif = enumeration.nextElement();                Enumeration<InetAddress> inetAddresses = nif.getInetAddresses();                if (inetAddresses != null)                    while (inetAddresses.hasMoreElements()) {                        InetAddress inetAddress = inetAddresses.nextElement();                        if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) {                            return inetAddress;                        }                    }            }        }        return null;    }}

把工具類 copy 到我們的 Android 項目中,繼續在 MainActivity.java 中編碼  

Android服務器怎么實現so文件調用

獲取了一下本機地址和 Android SDK 版本( Android 8 之后啟動 Service 方式不一樣)

申請權限,啟動 App

最后一步就是為 app 申請網絡權限了  

Android服務器怎么實現so文件調用

隨后連接我們的手機,運行項目,測試一下,點擊開啟服務  

Android服務器怎么實現so文件調用

看下 AndroidStudio 日志  

Android服務器怎么實現so文件調用

好像一切正常,在瀏覽器訪問下試試( ip 就是 App 中顯示的 ip 地址)  

Android服務器怎么實現so文件調用

如圖正常訪問到了我們想要的內容

回過頭來說下 Service,打開我們手機的設置,找到應用程序管理-運行中的服務(手機不同,方式不同)

Android服務器怎么實現so文件調用

可以看到我們的程序,運行了一個服務,這個服務就是咱們編碼的 MyService

Android服務器怎么實現so文件調用

接下來殺掉該 App進程,再次查看運行中的服務

Android服務器怎么實現so文件調用

讀到這里,這篇“Android服務器怎么實現so文件調用”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

高邮市| 奇台县| 西峡县| 财经| 柞水县| 毕节市| 潞城市| 日喀则市| 山东| 靖西县| 永胜县| 新干县| 庆阳市| 林西县| 龙南县| 贡山| 桦甸市| 河北省| 富阳市| 南昌县| 临桂县| 桐梓县| 博湖县| 和林格尔县| 新巴尔虎右旗| 开鲁县| 会昌县| 民权县| 平度市| 上饶市| 横山县| 淅川县| 启东市| 日喀则市| 旺苍县| 嘉定区| 尉犁县| 大悟县| 南宫市| 来宾市| 汽车|