2012-10-11 38 views
0

可能重複:
Can’t create handler inside thread that has not called Looper.prepare() inside AsyncTask for ProgressDialog無法在線程內部創建處理程序。我如何使用Looper.prepare()?

我開發一個Android的服務,嘗試獲取設備的IP地址每x時間,它comunicate到服務器。 我使用:

的Netbeans 7.2
Android SDK中
谷歌Android的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; 
     } 
    } 
} 

我認爲這個問題可能與線程,但我看不到的地方。任何幫助將不勝感激。

編輯:儘管我接受了其中一個正確的答案,或許正因爲此,我一直在尋找更多關於它的信息。我遇到了this page我想與大家分享一些需要了解此問題的人。它的作者Tejas Lagvankar以一種非常明確和可理解的方式解釋了關於線程,操作符和處理程序的所有信息。

回答

1

嘗試......

-首先聲明Handler對象引用變量在類範圍

Handler h;

-裏面的onCreate()方法創建的處理程序的實例。

h = new Handler();

-與線程使用它象下面這樣:

new Thread(new Runnable(){ 

public void run(){ 

    h.post(new Runnable(){ 


     // Do the UI work here. 

    }); 

} 


}); 

-可以很好地使用AsyncTask,在android系統提供,其被稱爲P * ainless線程。 *

+0

首先,我很抱歉沒有回答過。感謝您的時間和答案。我遵循你的指示,而且效果很好。但是,我不太確定這是否是一種非常正統的方式。我的方法現在看起來是這樣的: 私有類檢查擴展的TimerTask { @覆蓋 公共無效的run(){ h.post(新的Runnable(){ 公共無效的run(){ CheckIpAddress_Task checkIp =新CheckIpAddress_Task() ; checkIp.execute(); } }); } } 正如我所說,這個字,但它是正確的嗎? – Julio

1

處理程序始終在Looper線程上下文中運行。當你聲明一個單獨的線程時,它的上下文與Looper不同。因此錯誤。

簡單的解決方案總是在onCreate(),onStart()和onResume()中聲明處理程序。如果你使用AsyncTasks,你可以在onExExcute()和onPostExecute()中聲明處理程序,因爲它們也在Looper上下文中運行。

+0

謝謝你的回答。有了這些信息和Kumar Vivek Mitra's,我解決了我的問題。 – Julio

相關問題