開發APP中我們經常進行原生結合H5進行混合開發,下面將進行詳細講解Android原生集成MUI框架進行混合開發(項目Demo如下,有需要的可以下載查看),下一篇講述,Android原生和MUI(也適合H5與原生交互)交互的實現。
1:mui官方框架介紹及開發要點:(https://dev.dcloud.net.cn/mui/)如下爲官方頁面:
今天我們就要把這個號稱最接近原生開發的框架集成到我們Android原生本地中。
2:首先作爲例子我們下載下來mui的官方框架Hellomui,以hellomui這個框架集成到我們的Android原生本地中去。
下載完成後使用H5開發工具HBuild X打開hellomui項目如下(正常在手機上運行):
3:在該項目中有個manifest.json的文件,打開該文件其中有個基礎配置打開配置應用標識(AppID)點擊從雲端獲取後生成如下(真正的項目中配置各種你開發項目中需要的配置信息,如權限,啓動頁,SDK配置,源碼視圖等配置):
這個AppID是集成打原生中需要配置的。然後點擊運行—>原生App-本地打包—>生成本地App資源如下圖,等待一會打包成功後底部會有生成本地資源包的路徑至此H5端準備完畢:
4:在AndroidStudio中新建一個項目這裏我新建一個項目叫AndroidMUI項目,一直點擊下一步完成項目的構建(就是一個簡單的HelloWorld的界面顯示),然後下載Android集成需要的SDK(https://ask.dcloud.net.cn/article/103)找到最新的下載就可以了,下載後目錄如下(這裏有集成所需的全部配置和文件信息):
5:在AndroidStudio中打開AndroidMUI項目切換到project視圖—>app下的libs中添加如下文件(這裏只是簡單的選取幾個,文件是上圖中SDK目錄下的文件,這些文件很多可以適配所有開發者需要的類似於aar的SDK工具包,我們直接複製我們開發需要的並粘貼到app下的libs包中即可)如下所示:
6:在app—>src—>main文件夾下新建assets文件夾—>在改文件夾下新建兩個文件夾apps和data文件夾,然後把我們HBuildX中打包的文件複製到apps文件夾下,在data中複製對應的文件(上述第四步中下載的目錄中有個UniPlugin-Hello_AS文件夾,找到後打開是一個AndroidDemo項目,找到app—>src—>main文件夾下assets文件夾中的data文件夾下複製過來)配置後如下:
7:大開app下的build.gradle文件配置如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.andyyuan.androidmui"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
aaptOptions {
additionalParameters '--auto-add-overlay'
//noCompress 'foo', 'bar'
ignoreAssetsPattern "!.svn:!.git:.*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"
}
}
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation fileTree(include: ['*.aar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
8:在AndroidManifest.xml文件中添加如下權限配置:
<!--hellomui中需要的權限-->
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="RECEIVE_USER_PRESENT"/>
在application節點下配置如下:
<application
android:name=".MyApplication"
android:allowClearUserData="true"
android:hardwareAccelerated="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:largeHeap="true"
android:persistent="true"
tools:replace="android:name">
<activity
android:name="io.dcloud.PandoraEntry"
android:configChanges="orientation|keyboardHidden|keyboard|navigation"
android:hardwareAccelerated="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="portrait"
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>
<activity android:name=".MainActivity">
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.LAUNCHER" />-->
<!--</intent-filter>-->
</activity>
</application>
9:在assets下的data中dcloud_properties.xml文件中添加如下插件配置:
<feature name="PGPlugintest" value="com.example.andyyuan.androidmui.PGPlugintest"/>
10:新增PGPlugintest.java文件如下:
/**
* 5+ SDK 擴展插件示例
* 5+ 擴扎插件在使用時需要以下兩個地方進行配置
* 1 WebApp的mainfest.json文件的permissions節點下添加JS標識
* 2 assets/data/properties.xml文件添加JS標識和原生類的對應關係
* 本插件對應的JS文件在 assets/apps/H5Plugin/js/test.js
* 本插件對應的使用的HTML assest/apps/H5plugin/index.html
* <p>
* 更詳細說明請參考文檔http://ask.dcloud.net.cn/article/66
**/
public class PGPlugintest extends StandardFeature {
public void onStart(Context pContext, Bundle pSavedInstanceState, String[] pRuntimeArgs) {
/**
* 如果需要在應用啓動時進行初始化,可以繼承這個方法,並在properties.xml文件的service節點添加擴展插件的註冊即可觸發onStart方法
* */
}
//
// public void onStart(Context pContext, Bundle pSavedInstanceState, String[] pRuntimeArgs) {
//
// /**
// * 如果需要在應用啓動時進行初始化,可以繼承這個方法,並在properties.xml文件的service節點添加擴展插件的註冊即可觸發onStart方法
// * */
// }
//
public void PluginTestFunction(IWebview pWebview, JSONArray array)
{
Log.e(TAG, String.format("webview = %s, jsonArray = %s", pWebview, array));
// Toast.makeText(mApplicationContext, array.toString(), Toast.LENGTH_SHORT).show();
// 原生代碼中獲取JS層傳遞的參數,
// 參數的獲取順序與JS層傳遞的順序一致
String CallBackID = array.optString(0);
JSONArray newArray = new JSONArray();
newArray.put(array.optString(1));
newArray.put(array.optString(2));
newArray.put(array.optString(3));
newArray.put(array.optString(4));
// 調用方法將原生代碼的執行結果返回給js層並觸發相應的JS層回調函數
JSUtil.execCallback(pWebview, CallBackID, newArray, JSUtil.OK, false);
}
public String PluginTestFunctionSyncArrayArgu(IWebview pWebview, JSONArray array) {
JSONArray newArray = null;
JSONObject retJSONObj = null;
try {
newArray = array.optJSONArray(0);
String inValue1 = newArray.getString(0);
String inValue2 = newArray.getString(1);
String inValue3 = newArray.getString(2);
String inValue4 = newArray.getString(3);
retJSONObj = new JSONObject();
retJSONObj.putOpt("RetArgu1", inValue1);
retJSONObj.putOpt("RetArgu2", inValue2);
retJSONObj.putOpt("RetArgu3", inValue3);
retJSONObj.putOpt("RetArgu4", inValue4);
} catch (JSONException e1) {
e1.printStackTrace();
}
return JSUtil.wrapJsVar(retJSONObj);
}
public String PluginTestFunctionSync(IWebview pWebview, JSONArray array) {
String inValue1 = array.optString(0);
String inValue2 = array.optString(1);
String inValue3 = array.optString(2);
String inValue4 = array.optString(3);
String ReturnValue = inValue1 + "-" + inValue2 + "-" + inValue3 + "-" + inValue4;
// 只能返回String類型到JS層。
return JSUtil.wrapJsVar(ReturnValue, true);
}
}
OK,點擊編譯,運行成功!