0

可能重复:
无法在 AsyncTask 中为 ProgressDialog 调用 Looper.prepare() 的线程内创建处理程序

我正在开发一个 Android 服务,该服务尝试每 x 次获取设备 IP 地址并将其与服务器通信。我正在使用:

Netbeans 7.2
Android SDK
Android Google-Api 8
SQLite

我知道有一些与同一问题相关的问题,但没有一个问题能解决我的问题。正如您在下面的代码中看到的那样,我并没有尝试访问服务主线程的 UI(好吧,我试过了,但是在我注释了该行之后,错误仍然是一样的)。另一方面,我正在使用AsyncTask,我认为这是适当的方法。

这是我服务的主要部分:

public class ArsosService extends Service {

    private NotificationManager mNM;
        private final Messenger mMessenger = new Messenger(new IncomingHandler());
        protected DatabaseUtil dbu = null;
        @Override
        public void onCreate() {
            mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            try {
                dbu = DatabaseUtility.getInstance(this);
            } catch (IOException ex) {
                Log.e("Service", ex);
            }
            Timer timer = new Timer();
            timer.schedule(new Checks(), 0, 15000);
        }

        private class Checks extends TimerTask {
            @Override
            public void run() {
                CheckIpAddress_Task checkIp = new CheckIpAddress_Task();         
                checkIp.execute();
            }
        }

        // Other methods

        private class CheckIpAddress_Task extends AsyncTask<Void, Void, Integer> {
        @Override
        protected Integer doInBackground(Void... arg0) {
            String ipLocal = getLocalIpAddress();
            String text = null;

            // ipLocal==null means there is no available connection, so we do nothing. 
            if (ipLocal != null) {
                String ipDb = dbu.getLastIP(); // we get the IP saved in the DB.
                if (ipDb == null) {
                    dbu.addProperty("IP", ipLocal); // we save the IP in the DB.
                } else if (!ipLocal.equals(ipDb)) {
                    dbu.setProperty("IP", ipLocal); // we update the IP in the DB.
                }
            }
            if (text != null) {
                //showNotification(1, text, ipLocal);
            }
            return 0;
        }

        private String getLocalIpAddress() {
            String result = null;
            // Irrelevant code
            return result;
        }
    }
}

我认为问题可能与线程有关,但我看不出在哪里。任何帮助将不胜感激。

编辑:虽然我已经接受了其中一个答案是正确的,或者可能是因为它,但我一直在寻找更多关于它的信息。我遇到了这个页面,我想与所有有一天需要了解更多关于这个问题的人分享。它的作者 Tejas Lagvankar 以非常清晰易懂的方式解释了有关线程、loopers 和处理程序的所有内容。

4

2 回答 2

1

试试这个...

-首先在类范围内Handler声明对象引用变量。

Handler h;

-onCreate()方法内部创建Handler 的实例

h = new Handler();

-将它与如下线程一起使用:

new Thread(new Runnable(){

 public void run(){

    h.post(new Runnable(){


      // Do the UI work here.

   });

 }


});

-你可以很好地使用AsyncTaskandroid 中提供的,它被称为 P* ainless threading。*

于 2012-10-11T10:17:10.700 回答
1

Handler 总是在 Looper 线程上下文中运行。当你声明一个单独的线程时,它的上下文与 Looper 不同。因此错误。

简单的解决方案总是在 onCreate()、onStart() 和 onResume() 中声明处理程序。如果您使用 AsyncTasks,您可以很好地在 onPreExecute() 和 onPostExecute() 中声明处理程序,因为它们也在 Looper 上下文中运行。

于 2012-10-11T10:27:16.937 回答