1

ボタンを含むウィジェット (AppWidget) を開発する必要があります。ボタンが押されると http リクエストが実行され、リクエストが成功した場合、ウィジェットはトーストを介してその事実を通知します。http リクエストは UI をロックできるため、スレッドで実行します。トースト通知を除いて、すべて正常に動作しています(ログに「大丈夫」と表示されます)。私は何を間違っていますか?

AppWidgetProvider サブクラスで:

@Override
    public void onReceive(Context c, Intent intent){
        super.onReceive(c, intent);
        if(intent.getAction().equals(CLICK_ACTION)){
            performRequest(c);
        }
    }

(質問のonUpdateメソッドは不要だと思います)

private void performRequest(final Context c){
    new Thread(new Runnable(){
        public void run() {
            try {
                if(Http.get(URL).contains(SUCCESS)){
                Toast.makeText(c, "All right", Toast.LENGTH_SHORT).show();                                      
                Log.i("Widget","All right");        
                }
            } catch (Exception e) {
                e.printStackTrace();
            }}}).start();
}

Context問題は の引数だと思いますが、キーワードperformRequestを外すとエラーが出ます。final

アドバイスありがとう。

[編集]

私はこの方法で問題を「解決」しました:

Toast t-グローバル変数として宣言します。

- onReceive メソッド内で初期化しますToast.makeText(Context,String,int)

-表示する必要がある場合は、電話するだけですt.show()

より良い解決策があることを願っています。

4

3 に答える 3

2

http リクエストは UI をロックする可能性があるため、スレッドで実行します。トースト通知を除いて、すべて正常に動作しています(ログに「大丈夫」と表示されます)。私は何を間違っていますか?

問題は、別のスレッドから UI を変更できないことです。トーストを表示するには、このメッセージをメイン スレッドに戻す必要があります。


どうすればいいですか?

これを行うにはさまざまな方法があります。コンテキストをonReceive()フィールド変数として保存してみてください。

Context context;

@Override
public void onReceive(Context c, Intent intent){
    super.onReceive(c, intent);
    context = c;
    ...

次に、Activity に簡単なメソッドを作成します。

public void httpGetSucceeded() {
    Toast.makeText(context, "All right", Toast.LENGTH_SHORT).show();                                      
    Log.i("Widget","All right");        
}

Runnable 内でこれを呼び出します。

try {
    if(Http.get(URL).contains(SUCCESS)){
         httpGetSucceeded();
    }
} //etc
于 2013-02-27T00:21:25.483 に答える
0

さらに良いことに、スレッドがタスクを完了した後にメッセージをディスパッチするハンドラーを用意しないでください。ブロードキャスト レシーバーでそのメッセージを受信したら、メッセージを消費し、Handler オブジェクトの post runnable メソッドを使用してトーストを表示します。

ハンドラーはブロードキャスト レシーバーに属するため、ランナブルのポストを呼び出すときは、UI スレッドで実行する必要があります。

参照

http://developer.android.com/reference/android/os/Handler.html http://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable)

于 2013-02-27T00:28:06.687 に答える
-1

最も簡単な方法は、電話することです

activity.runOnUiThread(new Runnable() {
  public void run() {
    // launch toast here
  }
});

または、特定のウィジェットが与えられた場合:

view.post(new Runnable() {
  public void run() {
    // launch toast here
  }
});
于 2013-02-27T00:34:02.810 に答える