私はこの質問のような同じエラーのクラッシュレポートを持っています:WebView methods on same thread errorAndroidでWebViewを使用してJavascriptInterfaceを実装するベストプラクティス?
ここでは、Runnable()を作成することをお勧めします。
これが問題を解決する理由がわかりません。エラーは「同じスレッド上のWebviewメソッド」と表示されますが、その答えはUIスレッド(メインスレッド)上にメソッドを作成することを示唆しています。しかし、UIスレッドは唯一のスレッドではありませんか?誰かがこの全プロセスを詳細に説明できますか(コンストラクタ内のすべてのアクティビティで新しいWebviewを作成することを考慮して)? JavaScript関数/メソッドを実装する
私のコードは次のようになります。
public class JS_Bind {
private static final String TAG = "JS_Bind";
private Context context;
private AdvancedWebView mWebView;
public JS_Bind(Context c, AdvancedWebView mWebView) {
context = c;
this.mWebView = mWebView;
}
@JavascriptInterface
public void openActivity(String activityName) {
try {
Class activityClass = Class.forName(PACKAGE_NAME + "." + activityName);
context.startActivity(new Intent(MainActivity.this, activityClass));
} catch (ClassNotFoundException e) {
Toast.makeText(context, "Invalid activity name: " + activityName, Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
@JavascriptInterface
public void makeToast(String toast) {
Toast mToast = Toast.makeText(context, toast, Toast.LENGTH_SHORT);
mToast.setGravity(Gravity.CENTER, 0, 0);
mToast.show();
}
@JavascriptInterface
public void external(String url) {
mTracker.send(new HitBuilders.EventBuilder().setCategory("Action").setAction("External Link: " + url).build());
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
@JavascriptInterface
public String showToken() {
return gcmToken;
}
@JavascriptInterface
public int showUid() {
SharedPreferences pref = getSharedPreferences("Pref", Activity.MODE_PRIVATE);
int uid = pref.getInt("uid", 0);
return uid;
}
@JavascriptInterface
public void buyPremium() {
bp.purchase(MainActivity.this, PRODUCT_ID);
}
}
私はこのコード(first answer in the question I refered to)にEVERY機能を変更することがあります:
@JavascriptInterface
mWebView.post(new Runnable() {
@Override
public void makeToast() {
// ...
}
});
?ところで
が、これは私がコンストラクタでのWebViewを作成する方法ですonCreate
方法activies:
mWebView = (AdvancedWebView) findViewById(R.id.webView);
mWebView.setListener(this, this);
mWebView.addJavascriptInterface(new JS_Bind(this, mWebView), "Android");
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
if (!DetectConnection.checkInternetConnection(this)) {
mWebView.loadUrl("file:///android_asset/offline.html");
}
else {
mWebView.loadUrl("http://example.com/tw3/index.php?s=home");
}
申し訳ありませんが、私はすべてのJavascriptInterface関数をリストしていないことを忘れていました。私は自分の関数のどれがエラーを引き起こしたのかよく分かりません。私はあなたに残りを示すために1分で私の質問を更新します。 AsyncTaskでwebviewを使用することも考えましたが、それをお勧めしますか?セキュリティの問題について:1つのアクティビティごとに複数のハードコーディングされたメソッドを作成する必要がありますか? – AlexioVay
@Vaia: "AsyncTaskでwebviewを使用することも考えましたが、それをお勧めしますか?" - いいえ。 「1つのアクティビティごとに複数のハードコーディングされたメソッドを作成する必要がありますか?」それは改善になるだろう。または、渡された文字列に基づいて何の活動も盲目的に開くのではなく、入力を検証するだけです。 – CommonsWare
@Vaia:あなたはどこでも 'mWebView'を参照していません。だから、私はあなたがそれからエラーを得ることができる方法を見ていないが、私はまた、なぜあなたがそれを最初に持っているのか分からない。 – CommonsWare