AndroidとH 5のインタラクション-フレームワーク編
7941 ワード
現在、appの開発は主にnative app、hybrid app、web appの3つの方向に分かれている.個人的には3つのアプリの体験感が徐々に減っているような気がします.
hybrid appとweb appの開発の違いは、前者はフロントエンドに必要なインタフェースを自分で提供し、実現する必要があり、後者はいくつかのフレームワーク(例えばicon、dcloudなど)を借りていることである.実質的にはそれほど悪くないが、前者はもっと柔軟だ.Hybrid App開発におけるH 5とnativeのインタラクションがどのように行われているかまだ分からない場合は、この「AndroidとH 5インタラクション-基礎編」を見終わってもいいと信じています.
実はH 5とnativeのインタラクションもいくつかのステップであり、フロントエンドがオリジナルのインタフェースを統一的に呼び出すために、通常、フロントエンドとnative(iosとAndroid)エンドが規範化される.前の文章は主に両者の間でどのようにインタラクションを行うかを紹介していますが、この文章では両者のインタラクションに基づく簡単なパッケージを紹介します.フロントエンドにインタフェースを書く場合は、次のように書く可能性があります.
nativeインタフェースをこのように書くと、フロントエンドjs呼び出しは次のようになる可能性があります.
もちろんそう書いても大丈夫ですが、面倒だと思いますが、どう思いますか?
Androidインタフェースをこのように書くと、メンテナンスに問題があることに気づきます.第一に、このクラスは肥大化します.第二に、jsがAndroidインタフェースを呼び出すときはjsBrigdeというサブスレッドで実行され、Androidがjsメソッドを呼び出すときはmainスレッドで実行され、jsメソッドをコールバックする必要がある場合は、スレッドの切り替えが必要です.このクラスの各インタフェースメソッドを独立して1つのクラスに書き出し、統一されたインタフェースを介してフロントエンド呼び出しに露出し、jsメソッドを呼び出すときにプライマリスレッドに統一的に切り替えると、より良いのではないでしょうか.
では、どのようにカプセル化しますか?私の考えを紹介します.
Android:
Step 1はjsに統一呼び出しのインタフェースsendMessageを暴露する
Step 2 jsから送られてきたデータを統一的に処理する
Step 3スレッドをメインスレッドに切り替え、処理結果をフロントエンドに戻す
この3つのステップは核心的な考え方で、具体的な実現はここでコードを貼らないで、興味のあるのはソースコードを見ることができて、アドレスの文末は与えます.フロントエンドjsがどのようにカプセル化されているかを見てみましょう.
このコードは簡単ではないか.jsがnativeに送信するjsonデータフォーマットは固定されていることに注目すべきである.
how to use?
android端子:
1、まずはactivityで初期化
2.次に処理するアクションおよび対応する処理クラスを追加する
フロントエンド:
見終わったら先端もnative端も簡単だと思いますか?すべてのactionおよび渡されたパラメータフォーマットはカスタマイズでき、両端が統一されていることを保証するだけでよい.もしあなたが興味があれば、ソースコードはここでHybridBridgeで、startを歓迎して、何か問題があったら、私は改善を維持することができます.
作者:Jesse_zhaoリンク:https://www.jianshu.com/p/02afb387b6b4出典:簡書の著作権は作者の所有である.商業転載は著者に連絡して許可を得てください.非商業転載は出典を明記してください.
hybrid appとweb appの開発の違いは、前者はフロントエンドに必要なインタフェースを自分で提供し、実現する必要があり、後者はいくつかのフレームワーク(例えばicon、dcloudなど)を借りていることである.実質的にはそれほど悪くないが、前者はもっと柔軟だ.Hybrid App開発におけるH 5とnativeのインタラクションがどのように行われているかまだ分からない場合は、この「AndroidとH 5インタラクション-基礎編」を見終わってもいいと信じています.
実はH 5とnativeのインタラクションもいくつかのステップであり、フロントエンドがオリジナルのインタフェースを統一的に呼び出すために、通常、フロントエンドとnative(iosとAndroid)エンドが規範化される.前の文章は主に両者の間でどのようにインタラクションを行うかを紹介していますが、この文章では両者のインタラクションに基づく簡単なパッケージを紹介します.フロントエンドにインタフェースを書く場合は、次のように書く可能性があります.
/**
* dec: js
* createBy yjzhao
* createTime 2016/11/15 13:50
*/
public class NativeApi {
/**
*
*
* @param mobile
*/
@JavascriptInterface
public void openPhone(String mobile) {
...
}
/**
* ISP
*
* @param smsto
*/
@JavascriptInterface
public void opneMsg(String smsto) {
...
}
/**
*
*
* @param url URL
* @param data
* @param jsRe
*/
@JavascriptInterface
public void reqProxy(String url, String data, String jsRe) {
...
}
/**
*
*/
@JavascriptInterface
public String takePhoto(final String callback) {
...
}
/**
*
*/
@JavascriptInterface
public String selectPhoto(final String callback) {
...
}
/**
*
* @param urls ( , )
*/
@JavascriptInterface
public void browsePhoto(String urls){
....
}
/**
*
*
* @param url
* @return
*/
@JavascriptInterface
public String loadFile(String url) {
....
}
}
nativeインタフェースをこのように書くと、フロントエンドjs呼び出しは次のようになる可能性があります.
//
NativeAPI.openPhone(params);
//
NativeAPI.opneMsg(params);
//
NativeAPI.reqProxy(params);
//
NativeAPI.takePhoto(params);
//
NativeAPI.selectPhoto(params);
//
NativeAPI.browsePhoto(params);
//
NativeAPI.loadFile(params);
もちろんそう書いても大丈夫ですが、面倒だと思いますが、どう思いますか?
Androidインタフェースをこのように書くと、メンテナンスに問題があることに気づきます.第一に、このクラスは肥大化します.第二に、jsがAndroidインタフェースを呼び出すときはjsBrigdeというサブスレッドで実行され、Androidがjsメソッドを呼び出すときはmainスレッドで実行され、jsメソッドをコールバックする必要がある場合は、スレッドの切り替えが必要です.このクラスの各インタフェースメソッドを独立して1つのクラスに書き出し、統一されたインタフェースを介してフロントエンド呼び出しに露出し、jsメソッドを呼び出すときにプライマリスレッドに統一的に切り替えると、より良いのではないでしょうか.
では、どのようにカプセル化しますか?私の考えを紹介します.
Android:
Step 1はjsに統一呼び出しのインタフェースsendMessageを暴露する
private void addJavascriptInterface(WebView webView) {
webView.addJavascriptInterface(new Object(){
@JavascriptInterface
public void sendMessage(String jsonStr){
mHandleJsMessage.handle(jsonStr);
}
},"native");
}
Step 2 jsから送られてきたデータを統一的に処理する
/**
* js
* @param jsonStr js
* @return
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public boolean handle(String jsonStr) {
JsMessage jsMessage = new Gson().fromJson(jsonStr, JsMessage.class);
String action = jsMessage.getAction();
jsCallback = jsMessage.getCallback();
if (null == jsMessage.getAction())
return false;
if (HandleAction(jsonStr, action, mActionMap)) return true;
return false;
}
/**
* js action
* @param jsonStr js
* @param action js
* @param map js
* @return
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
private boolean HandleAction(String jsonStr, String action, Map> map) {
for (String mapAction : map.keySet()) {
if (mapAction.equals(action)) {
try {
mJsAction = map.get(mapAction).newInstance();
if (mJsAction != null) {
mJsAction.handleAction(mContext, jsonStr);
}
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return true;
}
}
return false;
}
Step 3スレッドをメインスレッドに切り替え、処理結果をフロントエンドに戻す
public void callback(final WebView webView, final String callback, final Object result){
//
Observable.create(new ObservableOnSubscribe
この3つのステップは核心的な考え方で、具体的な実現はここでコードを貼らないで、興味のあるのはソースコードを見ることができて、アドレスの文末は与えます.フロントエンドjsがどのようにカプセル化されているかを見てみましょう.
///////////////////////////////
// //
///////////////////////////////
;(function($) {
"use strict"//
function native(params) {
params = params||{};
if (params==="undefind")return;
if (params.action==="undefind")return;
// native , native
var Senddata={
action:params.action,
callback:"nativeCallback",
data:params.data,
}
window.nativeCallback = function(data) {
if (params.callback!=="undefind") {
params.callback(data);
}
}
var sendDataStr=JSON.stringify(Senddata);
window.native.sendMessage(sendDataStr);
}
$.native = native;
})($);
このコードは簡単ではないか.jsがnativeに送信するjsonデータフォーマットは固定されていることに注目すべきである.
{
"action":"action",
"callback":"nativeCallback",
"data":{ native action }
}
how to use?
android端子:
compile 'com.zyj:hybridbridge:0.1.0'//
1、まずはactivityで初期化
JsBridge.getInstance().init(this, webView)
2.次に処理するアクションおよび対応する処理クラスを追加する
JsBridge.getInstance().addJsAction(JsDeviceInfo.ACTION, JsDeviceInfo.class);
//JsDeviceInfo ( JsAction handleAction() )
public class JsDeviceInfo extends JsAction {
// action
public static final String ACTION = "deviceinfo";
@Override
protected void handleAction(Activity context, String jsonStr) {
HandleResult resultEntity =new HandleResult();
DeviceInfoEntity deviceInfoEntity =new DeviceInfoEntity();
deviceInfoEntity.setDeviceName(" Android !");
resultEntity.setData(deviceInfoEntity);
// ,post js callback
RxBus.getInstance().post(resultEntity);
}
}
フロントエンド:
function callback(backdata) {
//native
}
$.native({
action: "deviceinfo",
callback: callback
});
見終わったら先端もnative端も簡単だと思いますか?すべてのactionおよび渡されたパラメータフォーマットはカスタマイズでき、両端が統一されていることを保証するだけでよい.もしあなたが興味があれば、ソースコードはここでHybridBridgeで、startを歓迎して、何か問題があったら、私は改善を維持することができます.
作者:Jesse_zhaoリンク:https://www.jianshu.com/p/02afb387b6b4出典:簡書の著作権は作者の所有である.商業転載は著者に連絡して許可を得てください.非商業転載は出典を明記してください.