web-dev-qa-db-ja.com

サービス内からスレッドでrunOnUiThreadを呼び出すことができません

未読のSMSがある場合にSMSを20秒ごとにチェックするサービスを作成し、それを自分のWebサイトに送信してから、非同期タスクを使用してWebサイトにデータを投稿するために既読のマークを付けました(ボタンクリックタイプのアプリを作成して)手動で試したところ問題ありませんが、サイドサービスでは定義できません

runOnUiThread(new Runnable() {
            @Override
            public void run() { new MyAsyncTask().execute(sender,time,message);}
        });

識別できず、runOnUiThreadを定義するように求められます以下のコードで呼び出している場所からasynctaskを呼び出す方法はありますか

public class TestService extends Service {

    String sender = null;
    String time = null;
    String message = null;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        Toast.makeText(getApplicationContext(), "Service Created", 1).show();
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Toast.makeText(getApplicationContext(), "Service Destroy", 1).show();
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(getApplicationContext(), "Service Running ", 1).show();
        new Thread(new Runnable() {

            public void run() {
                ContentValues values = new ContentValues();
                Uri mSmsinboxQueryUri = Uri.parse("content://sms/inbox");
                String[] columns = new String[] { "_id", "thread_id",
                        "address", "person", "date", "body", "type" };
                Cursor cursor1 = getContentResolver().query(mSmsinboxQueryUri,
                    null, "read=0", null, null);
                DateFormat formatter = new SimpleDateFormat(
                    "dd/MM/yyyy hh:mm:ss.SSS");
                Calendar calendar = Calendar.getInstance();
                if (cursor1.getCount() > 0) {
                    cursor1.moveToFirst();
                    do {
                        // Retrieving sender number
                        sender = (cursor1.getString(cursor1
                            .getColumnIndex(columns[2])).toString());
                        // Retriving time of reception
                        long ms = cursor1.getLong(cursor1
                            .getColumnIndex(columns[4]));
                        calendar.setTimeInMillis(ms);
                        time = formatter.format(calendar.getTime()).toString();
                        // Retriving the message body
                        message = (cursor1.getString(cursor1
                            .getColumnIndex(columns[5])).toString());
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                new MyAsyncTask()
                                    .execute(sender, time, message);
                            }
                        });
                    } while (cursor1.moveToNext());// end of while
                }// end of if
                    // set as read
                values.put("read", true);
                getContentResolver().update(Uri.parse("content://sms/inbox"),
                    values, null, null);
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    private class MyAsyncTask extends AsyncTask<String, Integer, Double> {

        @Override
        protected Double doInBackground(String... params) {
            postData(params[0], params[1], params[2]);
            return null;
        }

        protected void onPostExecute(Double result) {
            // pb.setVisibility(View.GONE);
            Toast.makeText(getApplicationContext(), "command sent",
                Toast.LENGTH_LONG).show();
        }

        protected void onProgressUpdate(Integer... progress) {
            // pb.setProgress(progress[0]);
        }

        public void postData(String sender, String time, String message) {
            // Create a new HttpClient and Post Header
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(
                "http://www.mysite.co.nf/reciever.php");
            try {
                // Add your data
                List<NameValuePair> nameValuePairs = 
                                                new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("sender", sender));
                nameValuePairs.add(new BasicNameValuePair("time", time));
                nameValuePairs.add(new BasicNameValuePair("message", message));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                // Execute HTTP Post Request
                HttpResponse response = httpclient.execute(httppost);
            } catch (ClientProtocolException e) {} catch (IOException e) {}
        }
    }
}
17
Amit Swain

ServiceにはrunOnUiThread()というメソッドはありません。 ActivityのメソッドもServiceに対して定義されていると想定していますが、そうではありません。

解決策は、まさにそれを行うメソッドを定義することです。ここに簡略化した例を示します。残りのコードは変更されません。

_import Android.os.Handler;

public class TestService extends Service {

    Handler handler;

    @Override
    public void onCreate() {
        // Handler will get associated with the current thread, 
        // which is the main thread.
        handler = new Handler();
        super.onCreate();
    }

    private void runOnUiThread(Runnable runnable) {
        handler.post(runnable);
    }

}
_

詳細については、 ハンドラのドキュメントを参照 。特定のスレッドにいくつかの作業をダンプするために使用されます。この場合、UIスレッドは常にService.onCreate()を呼び出すため、HandlerはUIスレッドに関連付けられます。

58
wsanville