无法从服务内部的线程中调用 runOnUiThread [英] Not able to call runOnUiThread in a thread from inside of a service

查看:12
本文介绍了无法从服务内部的线程中调用 runOnUiThread的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做一个服务,如果有任何未读的短信,每 20 秒检查一次我的短信,然后将其发送到我的网站,然后标记为已读以将数据发布到网站我使用了 asynctask,当我手动尝试时它工作正常(通过制作按钮点击型应用程序)但在辅助服务中我无法定义

I wanted to make a service which will check my SMS in every 20 sec if there are any unread SMS then send it to my website then mark as read for posting data to website I used asynctask and it worked fine when I tried manually (by making button click type app) but in side service I cant define

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

无法识别并要求我定义runOnUiThread有什么方法可以从我调用下面代码的地方调用我的异步任务

it is unable to identify and asks me to define runOnUiThread Is there any way to call my asynctask from the place where I am calling in below code

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) {}
        }
    }
}

推荐答案

Service 没有名为 runOnUiThread() 的方法.您假设 Activity 中的方法也是为 Service 定义的,但事实并非如此.

Service does not have a method called runOnUiThread(). You're assuming that the method from Activity is also defined for a Service, but it's not.

解决方案,只需定义一个方法即可.这是一个简化示例,您的其余代码将保持不变.

Solution, just define a method that does exactly that. Here's a simplified example, the rest of your code would remain unchanged.

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);
    }

}

有关详细信息,请参阅 Handler 的文档.它用于将一些工作转储到特定线程上.在这种情况下,Handler 与 UI 线程相关联,因为 UI 线程总是调用 Service.onCreate().

For more info, see the docs for Handler. It's used to dump some work onto a specific thread. In this case, the Handler gets associated with the UI thread, since the UI thread always calls Service.onCreate().

这篇关于无法从服务内部的线程中调用 runOnUiThread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆