2010-05-09 62 views
2

我尝试在类中创建多个连接并更新主屏幕中的多个进度条。通过线程中的处理程序更新UI中的主要活动(Android)

但我有以下错误试图在Android中使用线程: 代码: 05-06 13:13:11.092:ERROR /的ConnectionManager(22854):ERROR:无法内螺纹创建的处理程序有不叫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中有几个任务时,进度条只在所有任务结束时更新。

预先感谢您的帮助

回答

5

Handler handler非最终和Init这里面onCreate()

+1

这是正确的。你不能在你的类定义中调用'new Handler()'(这甚至不是正确的java;你只能在类定义中初始化一个* static *对象)。另外,没有理由让它成为最终的。处理程序绑定到创建它的线程,并且该线程必须运行消息队列/活套。将它放在'onCreate()'中是将你的处理程序绑定到主UI线程的正确方法。 – stormin986 2010-05-09 23:07:07

+8

@ stormin986你错了..如果我们想要的话,我们可以肯定地调用新的方法(但是这被认为是一种不好的做法),接下来你说“你只能在类定义中初始化一个静态对象”,你又错了,我们可以初始化我们在类中使用的任何变量定义... – aProgrammer 2012-08-10 10:46:09

3

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

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

我不确定是什么原因导致进度条只更新一次,但肯定是某处的逻辑错误。 尝试登录您应用程序的不同步骤-ie。在发送消息之前,并在处理它时。

0

HRK,所述遮蔽部件是当你声明一个局部变量,其具有相同的名称作为该领域的方法中:

Handler handler = ... 

要使用字段,则省略类型:

handler = ... 

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

相关问题