MUI離線打包及插件開發(fā)

一、mui離線打包

工具:Android Studio、HBuilder、5+ SDK

1、下載5+ SDK(http://ask.dcloud.net.cn/article/103)
2、使用Android Studio創(chuàng)建一個新項目
3、復(fù)制SDK->libs->lib.5plus.base-release.aar文件到原生工程工程的app->libs目錄下

aar.png

4、打開項目app目錄下的build.gradle文件,將aar包添加引用,加入如下代碼:

implementation fileTree(dir: 'libs', include: ['*.aar'])


5、修改工程的targetSdkVersion大于等于21


targetSdkVersion.png

6、打開工程的Androidmanifest.xml文件,復(fù)制以下內(nèi)容替換該文件中原有application節(jié)點下的內(nèi)容

    <application
        android:name="io.dcloud.application.DCloudApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <!-- 啟動頁 -->
        <activity
            android:name="io.dcloud.PandoraEntry"
            android:configChanges="orientation|keyboardHidden|screenSize|mcc|mnc|fontScale"
            android:hardwareAccelerated="true"
            android:screenOrientation="user"
            android:theme="@style/TranslucentTheme"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

注:若自定義application,可采取繼承DCloudApplication,添加tools:replace="android:name"至application節(jié)點下,避免merge沖突。

7、復(fù)制SDK->assets->data目錄和目錄下的文件到工程的src->main->assets目錄下,新創(chuàng)建的工程默認(rèn)沒有assets目錄,可在與java同級目錄下創(chuàng)建assets目錄。


assets.png

注: apps目錄下應(yīng)用資源的路徑為[appid].www, appid為應(yīng)用資源manifest.json文件中id節(jié)點的值,也就是mui項目manifest.json里的appid,如下圖:


mui_manifest.png

8、將HBuilder里的代碼進(jìn)行本地打包,將應(yīng)用資源打包進(jìn)入Android項目的assets->apps對應(yīng)目錄下,HBuilder點擊發(fā)行->本地打包->生成本地打包App資源,將路徑選擇到apps即可。


dabao.png

9、修改assets->data->dcloud_control.xml文件的apps->app->appid屬性的值改為當(dāng)前應(yīng)用manifest.json文件id節(jié)點的值


control.png

運行項目,App便可進(jìn)入到mui的頁面,但是你會發(fā)現(xiàn)第一個頁面是這樣的


welcome.png

這是因為io.dcloud.PandoraEntry入口會先加載一個Splash頁面,暫時不知道如何去掉,我們需要將應(yīng)用的圖標(biāo)(文件名為icon.png)和啟動圖片(文件名為splash.png)放入drawable中,這樣Splash頁面就顯示你的splash圖片,如圖


icon_splash.png
splash.png

二、插件開發(fā)

mui文檔傳送門

官方文檔一開始可能看的有點蛋疼,這里就寫個通俗點的例子,利用插件開發(fā)來進(jìn)行動態(tài)權(quán)限申請,也就是在mui利用插件到原生里進(jìn)行動態(tài)申請權(quán)限,然后將結(jié)果回調(diào)到mui這邊js里。

1、JS擴(kuò)展插件編寫

實現(xiàn)同步擴(kuò)展方法時,調(diào)用JS Plugin Bridge的window.plus.bridge.execSync()
方法,該方法可同步獲取Native插件返回的運行結(jié)果。

void plus.bridge.execSync( String service, String action, Array<String> args ); 

實現(xiàn)異步擴(kuò)展方法時,調(diào)用JS Plugin Bridge的plus.bridge.exec()方法,該方法會通知Native層插件執(zhí)行指定方法,運行結(jié)果會通過回調(diào)的方式通知JS層。

void plus.bridge.exec( String service, String action, Array<String> args );  
test.js.png
2、實現(xiàn)擴(kuò)展插件類
(1) 創(chuàng)建一個繼承自StandardFeature的類

創(chuàng)建一個繼承自StandardFeature的類,實現(xiàn)第三方插件擴(kuò)展。
創(chuàng)建插件類需要引入的包

import io.dcloud.DHInterface.IWebview;
import io.dcloud.DHInterface.StandardFeature;
import io.dcloud.util.JSUtil;


(2) 實現(xiàn)擴(kuò)展方法

Native層擴(kuò)展插件的方法名需要和JS Plugin Bridge里windows.plus.bridge.exec()或windows.plus.bridge.execSync()方法的第二個傳入?yún)?shù)相同,否則無法調(diào)用到指定的方法。

public void PluginTestFunction(IWebview pWebview, JSONArray array) 


(3) 返回值到j(luò)s層

同步執(zhí)行方法:
同步執(zhí)行方法在返回結(jié)果時可以直接將結(jié)果以return的形式返回給js層,返回的結(jié)果需要調(diào)用如下方法處理要返回的字符串。

JSUtil.wrapJsVar("Html5 Plus Plugin Hello1!",true);  

異步執(zhí)行方法:

JSUtil.execCallback(pWebview, cbId, (which==AlertDialog.BUTTON_POSITIVE)?"ok":"cancel", JSUtil.OK, false, false);   


3、關(guān)聯(lián)JS插件名和原生類

在Android原生工程的assets\data\dcloud_properties.xml文件中聲明插件類別名和Native層擴(kuò)展插件類的對應(yīng)關(guān)系

<properties>
    <features>
        ...
        <feature name="plugintest" value="com.kmvc.H5PlusPlugin.PGPlugintest"/>
    </features>

    <services>
        ...
        <service name="plugintest" value="com.kmvc.H5PlusPlugin.PGPlugintest"></service>
    </services>
</properties>

注:上面的value值便是擴(kuò)展插件類的路徑。

在應(yīng)用的manifest.json文件中還需要添加擴(kuò)展插件的應(yīng)用使用權(quán)限,permissions節(jié)點下添加如下:


manifest_permission.png



4、使用實例

上面便是插件開發(fā)的核心步驟,下面舉個例子,就是上面說的動態(tài)權(quán)限申請
(1)、html調(diào)用上面寫好的js擴(kuò)展插件,js擴(kuò)展插件將調(diào)用原生那邊的插件類相應(yīng)方法

plus.plugintest.PluginTestFunction("PermissionCheck", "Plus", "AsyncFunction", "MultiArgument!", function(
                        result) {
    if(result[0] == "MyPermissionOK") {
        //getVersion();
    } else if(result[0] == "MyPermissionDenied") {
        mui.alert("關(guān)鍵權(quán)限必須打開,請進(jìn)入設(shè)置打開相關(guān)權(quán)限,否則將影響應(yīng)用正常使用!", "提示", function() {
        //getVersion();
        })
    } else {
        mui.alert("關(guān)鍵權(quán)限必須打開,請進(jìn)入設(shè)置打開相關(guān)權(quán)限,否則將影響應(yīng)用正常使用!", "提示", function() {
        //getVersion();
        })
    }
}, function(result) {
    mui.alert("權(quán)限申請失敗,請進(jìn)入設(shè)置打開相關(guān)權(quán)限,否則將影響應(yīng)用正常使用!", "提示", function() {
    //getVersion();
    })
});

(2)、原生插件類被調(diào)用之后獲取js傳過來的值,并跳轉(zhuǎn)到權(quán)限申請的原生頁面

    public void PluginTestFunction(IWebview pWebview, JSONArray array) {
        // 原生代碼中獲取JS層傳遞的參數(shù),
        // 參數(shù)的獲取順序與JS層傳遞的順序一致
        mWebview=pWebview;
        CallBackID = array.optString(0);
        String Method = array.optString(1);
        JSONArray newArray = new JSONArray();
        String par1 = array.optString(2);
        String par2 = array.optString(3);
        String par3 = array.optString(4);
        String par14 = array.optString(5);

        if("PermissionCheck".equals(Method)){
            Intent intent = new Intent(mContext, XXX.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("CallBackID",CallBackID);
            mContext.startActivity(intent);
        }
    }

(3)、權(quán)限申請的原生頁面獲取完權(quán)限申請結(jié)果后調(diào)用異步或同步方法回調(diào)到j(luò)s層,這里用的異步,如下

 if(permission.granted){
       // All permissions are granted !
       JSUtil.execCallback(iWebview, callBackID, new JSONArray().put("MyPermissionOK"), JSUtil.OK, false);
       finish();
 }else if(permission.shouldShowRequestPermissionRationale){
       // At least one denied permission without ask never again
       JSUtil.execCallback(iWebview, callBackID, new JSONArray().put("MyPermissionDenied"), JSUtil.OK, false);
       finish();
}else{
      // At least one denied permission with ask never again
      JSUtil.execCallback(iWebview, callBackID, new JSONArray().put("MyPermissionNeverAsked"), JSUtil.OK, false);
      finish();
}

上面的代碼重點在JSUtil.execCallback方法,就是用來回調(diào)到j(luò)s層的,具體參數(shù)如下

iWebView:擴(kuò)展插件方法運行的窗口
callBackID:回調(diào)函數(shù)的唯一標(biāo)識
pMessage:回調(diào)函數(shù)的參數(shù)
pStatus:操作是否成功,成功則使用JSUtil.OK,否則使用錯誤代碼
isJson:回調(diào)函數(shù)參數(shù)是否為JSON數(shù)據(jù)

回調(diào)到j(luò)s層后便可根據(jù)返回的結(jié)果進(jìn)行處理,如上面第(1)步,我們根據(jù)權(quán)限申請的情況進(jìn)行相應(yīng)提示,并做了版本檢查更新操作。

最終效果:


apply.png

ps:動態(tài)權(quán)限申請,需要targetSdkVersion大于等于23。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容