2

我尝试在一个类中建立多个连接并更新主屏幕中的多个进度条。

但是我在尝试在 android 中使用线程时遇到以下错误:代码:05-06 13:13:11.092:错误/连接管理器(22854):错误:无法在未调用 Looper.prepare 的线程内创建处理程序( )

这是我在主活动中的一小部分代码

public class Act_Main extends ListActivity 
{ 
 private ConnectionManager cm; 

 public void onCreate(Bundle savedInstanceState) 
 { 
      super.onCreate(savedInstanceState); 

      // Set up the window layout 
      requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
      setContentView(R.layout.main); 
      getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title); 
 } 

 public void startConnection() 
 { 
      //open DB connection 
      db = new DBAdapter(getApplicationContext()); 
      db.open(); 

      cm = new ConnectionManager(handler, db); 
      showDialog(DIALOG_PROGRESS_LOGIN); 
 } 

 @Override 
 public void onStart() 
 { 
      super.onStart(); 
      startConnection(); 
 } 

 protected Dialog onCreateDialog(int id) 
 { 
      switch (id) 
      { 
      case DIALOG_PROGRESS_LOGIN: 
           progressDialog = new ProgressDialog(Act_Main.this); 
           progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
           progressDialog.setMessage("Connecting.\nPlease wait..."); 
           progressThreadLogin = new ProgressThreadLogin(); 
           progressThreadLogin.start(); 

           return progressDialog; 
      case DIALOG_PROGRESS_NETWORK: 
           [b]progressDialog = new ProgressDialog(Act_Main.this);[/b] 
           progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
           progressDialog.setMessage("Loading entire network.\nPlease wait..."); 
           progressThreadNetwork = new ProgressThreadNetwork(); 
           progressThreadNetwork.start(); 

           return progressDialog; 
      default: 
           return null; 
      } 
 } 


 // Define the Handler that receives messages from the thread and update the progress 
 final Handler handler = new Handler() 
 { 
      public void handleMessage(Message msg) 
      { 
           int total = msg.getData().getInt("total"); 
           int step = msg.getData().getInt("step"); 

           Log.d(TAG, "handleMessage:PROCESSBAR:"+total); 
           progressDialog.setProgress(total); 

           if (total >= 100) 
           { 
                switch (step) 
                { 
                     case UPDATE_NETWORK: 
                          dismissDialog(DIALOG_PROGRESS_LOGIN); 
                          showDialog(DIALOG_PROGRESS_NETWORK); 
                          cm.getNetwork(); 
                          break; 
                                    .... 
                     default: 
                          break; 
                } 
           } 
      } 
 }; 

 private class ProgressThreadLogin extends Thread 
 { 
      ProgressThreadLogin() { } 
      public void run() { cm.login(); } 
 } 

 private class ProgressThreadNetwork extends Thread 
 { 
      ProgressThreadNetwork() { } 
      public void run() { cm.getNetwork(); } 
 } 
}

还有我的 connectionManager 类:

public class ConnectionManager 
{ 
 public ConnectionManager(Handler handler, DBAdapter db) 
 { 
      this.handler = handler; 
      this.db = db; 
 } 

 public void updateProgressBar(int step, int value) 
 { 
      if (value == 0) 
           total = total+1; 
      else 
           total = value ; 

      Message msg = handler.obtainMessage(); 
            Bundle b = new Bundle(); 
            b.putInt("total", total); 
            b.putInt("step", step); 
            msg.setData(b); 
            handler.handleMessage(msg); 
 } 

 public void login() 
 { 
            //DO MY LOGIN TASK 
      updateProgressBar(Act_Main.UPDATE_NETWORK, 100); 
 }
}

崩溃错误发生在“case DIALOG_PROGRESS_NETWORK:”的第一行。我的第一个进度条被隐藏,但第二个没有显示。

我认为我使用线程和处理程序做错了,但我不知道为什么。

我首先使用 handler.sendMessage 代替 handler.handleMessage 但是当我的 connectionManager 中有多个任务时,进度条仅在所有任务结束时更新。

预先感谢您的帮助

4

3 回答 3

5

Handler handler非最终的并在里面初始化它onCreate()

于 2010-05-09T21:18:45.363 回答
3

拥有 Handler final 并在类定义中声明它是非常好的。此外,当您在 onCreate 中初始化处理程序时,在最后一段代码中,您实际上是在“隐藏”您的类中声明的处理程序,因此没有初始化它。我很惊讶你没有任何 NullPointerException。

但在 ConnectionManager::updateProgressBar 中,您确实需要调用 sendMessage(),因为通过直接调用 handleMessage(),处理程序会从 ConnectionManager::updateProgressBar 的线程(可能不是 UI 线程)中调用。

我不确定是什么导致了进度条只更新一次的问题,但这肯定是某个地方的逻辑错误。尝试在您的应用程序的不同步骤登录 - 即。在发送消息之前,以及在处理它时-。

于 2010-05-10T11:45:26.660 回答
0

Hrk,阴影部分是当您在方法内声明一个与字段同名的局部变量时:

Handler handler = ...

要使用该字段,请省略类型:

handler = ...

关于异常,只需ProgressDialog在主线程中实例化对象(例如,在 onCreate() 方法中)并稍后调用它的 show() 方法之一。

于 2010-05-16T15:52:22.643 回答