1

私はいくつかの仕事をしており、最後に私のasynctask(その名前は背景です)を実行するサービスを持っています。 asyncTaskでは、onPostExecute()でalertDialogを表示します。 私のアプリケーションをデバッグするとき、私のasyncTaskを実行する行で私のサービスでエラーが発生します。このライン:サービスから呼び出されたasyncTaskのalertDialogを表示する際にエラーが発生しましたか?

backGround=new BackGround(context); backGround.execute(String.valueOf(send_json))

私は、エラーが原因で、私はasyncTaskに送信コンテキストのaccuresことを知っています。 私はgetApplicationContext()を適用します。 & getBaseContext(); &もサービスのコンテキストです。エラーは消滅しません。 このコードをmainActivityのコンテキストに適用し、エラーは発生しないので、このエラーは、サービスからasyncTaskのコンストラクタに送信するコンテキストが原因であると確信しています。

どうすればいいですか? 私は助けていただきありがとうございます。

編集:これはエラーです。

public class BackGround extends AsyncTask < String , Void , String > { 
Context context; 
AlertDialog alertDialog; 
public BackGround(Context context){ 
    this.context=context; 
} 

@Override 
protected String doInBackground(String... params){ 
String location_url ="http://192.168.1.90/server_connection.php"; 
    try{ 
     URL url1=new URL(location_url); 
     HttpURLConnection httpURLConnection =   (HttpURLConnection)url1.openConnection(); 
     httpURLConnection.setRequestMethod("POST"); 
     httpURLConnection.setDoOutput(true); 
     httpURLConnection.setDoInput(true); 
     OutputStream stream_upload=httpURLConnection.getOutputStream(); 
     BufferedWriter buffer_writer=new BufferedWriter(new OutputStreamWriter(stream_upload,"UTF-8")); 
     // String PostData= URLEncoder.encode() 

     buffer_writer.write(String.valueOf(params)); 


     buffer_writer.flush(); 
     buffer_writer.close(); 
     stream_upload.close(); 





     InputStream stream_dawnload=httpURLConnection.getInputStream(); 
     BufferedReader bufferreader=new BufferedReader(new InputStreamReader(stream_dawnload,"iso-8859-1")); 
     String result=""; 
     String line; 
     while ((line = bufferreader.readLine()) != null) { 
      result += line;} 
     bufferreader.close(); 
     stream_upload.flush(); 
     stream_dawnload.close(); 
     httpURLConnection.disconnect(); 

     return result; 



    }catch (Exception e){ 
     e.printStackTrace(); 
    } 

    return null; 

}これが私のサービスのコードである

@Override 
protected void onPreExecute() { 
    alertDialog = new AlertDialog.Builder(context).create(); 
    alertDialog.setTitle("Login status"); 
} 

@Override 
protected void onPostExecute(String result) { 

    alertDialog.setMessage(result); 
    alertDialog.show(); 
} 

09-08 18:39:35.253 20251-20813/ir.blog.trafik E/AndroidRuntime: FATAL EXCEPTION: Timer-0 
                     java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
                      at android.os.Handler.<init>(Handler.java:197) 
                      at android.os.Handler.<init>(Handler.java:111) 
                      at android.app.Dialog.<init>(Dialog.java:111) 
                      at android.app.AlertDialog.<init>(AlertDialog.java:114) 
                      at android.app.AlertDialog$Builder.create(AlertDialog.java:931) 
                      at ir.blog.trafik.BackGround.onPreExecute(BackGround.java:88) 
                      at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586) 
                      at android.os.AsyncTask.execute(AsyncTask.java:534) 
                      at ir.blog.trafik.locationService.json_maker(locationService.java:538) 
                      at ir.blog.trafik.locationService$1.run(locationService.java:588) 
                      at java.util.Timer$TimerImpl.run(Timer.java:284) 

この

は私のasyncTaskクラスです

public class locationService extends Service{Context context;BackGround backGround ; 


@Override 
public void onCreate() { 
     context =this; 
    } 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

Toast.makeText(context,"service started",Toast.LENGTH_LONG).show(); 


    doSomeThingRepeatedly(context); 


    return Service.START_FLAG_REDELIVERY; 



} 

、これは私のdoSomeThingReapetedly()メソッドであります私はonStartcommanでそれを呼んだD()

private void doSomeThingRepeatedly(final Context context) { 
    timer.scheduleAtFixedRate(new TimerTask() { 

     @Override 
     public void run() { 
...... 
     backGround=new BackGround(context); 
    backGround.execute(String.valueOf(send_json)); 
} 


    }, 0, UPDATE_INTERVAL); 

) "Pravin Divraniyaの" 溶液を添加した後、それが正常に動作しますが、エラーが(onPostExecuteのデバッグの後asyncTaskに発生し、doInBackground(にintering)、そのエラーは次のとおりです。

FATAL EXCEPTION: main 
                     android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application 
                      at android.view.ViewRootImpl.setView(ViewRootImpl.java:804) 
                      at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:288) 
                      at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:73) 
                      at android.app.Dialog.show(Dialog.java:287) 
                      at ir.blog.trafik.BackGround.onPostExecute(BackGround.java:103) 
                      at ir.blog.trafik.BackGround.onPostExecute(BackGround.java:22) 
                      at android.os.AsyncTask.finish(AsyncTask.java:631) 
                      at android.os.AsyncTask.access$600(AsyncTask.java:177) 
                      at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 
                      at android.os.Handler.dispatchMessage(Handler.java:99) 
                      at android.os.Looper.loop(Looper.java:176) 
                      at android.app.ActivityThread.main(ActivityThread.java:5493) 
                      at java.lang.reflect.Method.invokeNative(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:525) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1225) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1041) 
                      at dalvik.system.NativeStart.main(Native Method) 
+0

エラーメッセージを投稿できますか? – thunder413

+0

あなたのコードを投稿してください。 –

+0

@ thunder413私は編集し、私はエラーマッサージを追加しました。 –

答えて

0

受信機を登録することを忘れてはいけない(スレッディングルールセクションを読む)

  1. AsyncTaskクラスは、UIスレッドでロードする必要があります。これはJELLY_BEANの時点で自動的に行われます。
  2. タスク・インスタンスは、UIスレッドで作成する必要があります。
  3. UIスレッドでexecute(Params ...)を呼び出す必要があります。
  4. onPreExecute()、onPostExecute(Result)、doInBackground(Params ...)、onProgressUpdate(Progress ...)を手動で呼び出さないでください。
  5. タスクは一度だけ実行することができます(第2の実行が試行された場合、例外がスローされます。)

あなたがHandlerを使用してそれを行うことができます繰り返し操作をしたい場合。 onStartCommandでハンドラーを作成します(UIスレッドから)。そのハンドラを使用してAsyncTaskをトリガします。

private Handler mHandler = null; 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     ... 
     mHandler = new Handler(); 
     mHandler.postDelayed(runnable,1000); 
//Here 1000 is delayMillis, you can set your delay here. 
    } 

サービスクラス内でRunnableクラスインスタンスを作成し、そこからAsyncTaskを呼び出します。

Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
      backGround=new BackGround(context); 
      backGround.execute(String.valueOf(send_json)); 
     } 
    }; 

あなたが実行可能にrepetedの呼び出しを停止したい場合は、単にmHandler.removeCallbacks(runnable);

更新呼び出し: - 私たちはそう下記のサービスコンテキストで、通常の警告]ダイアログが表示さカント する2つの解決策です。

解決策1: -

我々は、それがシステム警告ダイアログである場合にのみサービスからダイアログを表示することができます。それはSYSTEM_ALERT_WINDOWの許可を必要とする、

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 

をしかし:だから、次のようにダイアログにTYPE_SYSTEM_ALERTウィンドウレイアウトパラメータを設定します。したがって、マニフェストファイルにこのpermissinを追加することを忘れないでください。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 

解決策2: -

活動を開始し、Theme.Dialogへの活動のテーマを設定してください。 ApiDemoプロジェクトにデモがあります。アクティビティやアプリケーションにテーマを適用する方法については、thisのリンクを確認してください。情報だけのため

  1. 独自のスレッドを作成しません。そのホストプロセス・サービスのメインスレッドで実行さService 、あなたがマニフェストに指定しない限り、(別のプロセスで実行されません。さもないと)。 IntentServiceはワーカースレッド(UIThread以外)で実行されます。

  2. 私たちがハンドラインスタンスを作成すると、それが作成されたスレッドに関連付けられているため、mHandler.postDelayedを任意のスレッドから呼び出すことができます。私たちの場合は、onStartCommandメソッドで作成しているので、UIThreadです。

お気軽にお問い合わせください。

これがあなたを助け、あなたの疑問を解決することを願っています。

+0

ありがとう、それは魅力のように働く:)。何か重要なのは "import android.os.Handler"ですが、このコードを追加した後にエラーが発生します: –

+0

私はそれを私の質問に追加します、THANK U. –

+0

また、私は追加した追加情報に感謝しています。とても便利です。 –

0

ワーカースレッドで実行されているdoInBackground()内にダイアログを作成していますが、要件に応じてonPreExecuteまたはonPostExecuteに作成してみてください。

+0

私のコードを追加しました。お手伝いできますか? –

0

私はサービス魔法使いからuiを起動したいという事実がメインスレッド上で実行されておらず、サービスにはrunOnUiThreadの実装がないと思うと思います。作業用のarroundはLocalBroadcastManagerとすべての活動のbroadcastreceiverとfrgamentにすべての活動では、あなたのサービス

Intent intent = new Intent("showDialog"); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 

でサンプル例

以下の活動からダイアログを開き

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     String action = intent.getAction(); 
     if(action.equals("showDialog")) { 
      // Show your dialog here 
     } 
    } 
}; 

そしてAsynkTaskドキュメントを1として

// Register receiver onStart/onCreate 
    LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,new IntentFilter("showDialog")); 
    // Unregister onDestroy 
    LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver); 
+0

はい、私には、タイマーがあり、timerTaskが宣言されたときに知っているように、新しいスレッドが準備されているという機能を持つサービスがあります。私は自分のコードを使用します:backGround = new BackGround(context); timerTaskのbackGround.execute(String.valueOf(send_json))...しかし、私はあなたの答えを理解していませんでした: "私はこのコードを追加する必要がありますfrgament上の任意の活動では、言った? –

+0

私は私の質問を編集し、私は私のサービスclass.plzを追加して、それを確認して、uをありがとう。 –

関連する問題