2016-06-24 4 views
1

私はこの質問のような同じエラーのクラッシュレポートを持っています: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"); 
} 

答えて

1

をしかし、一つのUIは、スレッドとスレッドだけではないのですか?

番号WebViewには、独自のスレッドプールがあります。 many other threads in an Android applicationがあります。

私はこのコード必ずしも

ないためにすべての機能を変更する必要があります。

まず、上記の@JavascriptInterfaceメソッドのエラー(A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread.)がどのように表示されるのかわかりません。そのエラーは、WebViewのメソッドを呼び出すときで、それをやっていないときです。

場合はrunOnUiThread()(または同等の技術)を使用する必要があります:あなたの@JavascriptInterface方法はWebView自体、または

  • なければならない何かを行うにはあなたの@JavascriptInterface試みを参照してください

    • メインのアプリケーションスレッドで行われます(別のエラーメッセージが表示されるのは、特にWebViewに関連付けられないためです)

    startActivity()呼び出しをメインのアプリケーションスレッドで呼び出す必要があるかもしれない—これはバックグラウンドスレッドで呼び出すことができるかどうかを忘れています。同様にあなたのToast作業—と私はバックグラウンドスレッドで行うことができると思うが、私はそれを確信していません。私はバックグラウンドスレッドからこれらの事のいずれかをやってみたので、それは年を経ています。あなたはWebViewに表示されているものの一つ一つのバイトをコントロールしている場合


    また、唯一のあなたのコードを使用してください。 startActivity()を任意のWebコンテンツに公開することは、セキュリティに大きな影響を与えます。

  • +0

    申し訳ありませんが、私はすべてのJavascriptInterface関数をリストしていないことを忘れていました。私は自分の関数のどれがエラーを引き起こしたのかよく分かりません。私はあなたに残りを示すために1分で私の質問を更新します。 AsyncTaskでwebviewを使用することも考えましたが、それをお勧めしますか?セキュリティの問題について:1つのアクティビティごとに複数のハードコーディングされたメソッドを作成する必要がありますか? – AlexioVay

    +0

    @Vaia: "AsyncTaskでwebviewを使用することも考えましたが、それをお勧めしますか?" - いいえ。 「1つのアクティビティごとに複数のハードコーディングされたメソッドを作成する必要がありますか?」それは改善になるだろう。または、渡された文字列に基づいて何の活動も盲目的に開くのではなく、入力を検証するだけです。 – CommonsWare

    +0

    @Vaia:あなたはどこでも 'mWebView'を参照していません。だから、私はあなたがそれからエラーを得ることができる方法を見ていないが、私はまた、なぜあなたがそれを最初に持っているのか分からない。 – CommonsWare

    関連する問題