Как передать значение прогресса из потока в действие?
У меня проблема с дизайном, отправляющая значение индикатора выполнения из класса, вызываемого из потока в классе Activity для обновления GUI, как показано ниже
[фрагмент кода не компилируется, он предназначен только для объяснения]:
Class A : Extend Activity {
new Thread(new Runnable()
{
public void run()
{
B objB = new B();
objB.DownloadFile();
}
}).start();
}
Class B {
public void DownloadFile()
{
... some work [preparing SOAP request]
while(response.read())
{
//send calculated progress to Class A to update the progress value
}
}
}
любая помощь или руководство будет принята с благодарностью
3 ответов
вы можете сделать метод updateProgressBar в классе A, а затем передать класс B ссылку на класс A. класс B может затем вызвать функцию обратного вызова в A (возможно, передать int или что-то еще, чтобы указать, насколько далеко прогресс). Обновление пользовательского интерфейса из другого потока, то поток пользовательского интерфейса, как правило, вызывает проблемы. К счастью, класс Activity имеет метод " runOnUiThread (Runnable action)". Поэтому, чтобы установить прогресс, вы можете сделать что-то вроде:
while(response.read()){
//do stuff here
int progress = getProgress(); //set the progress to something
a.runOnUiThread(new Runnable(){
a.updateProgress(progress);
});
}
я использовал Handler
для достижения этого эффекта. Создайте его в Activity
что вы создаете ProgressDialog
В, затем передать Handler
в maethod вы хотите получить прогресс от. Затем вы можете отправить сообщение обратно на вызов Activity
для обновления прогресса:
public class ClassA extends Activity {
...
private static final int HANDLER_MESSAGE_PERFORM_DIALOG_UPDATE = 0;
...
new Thread(new Runnable()
{
public void run()
{
B objB = new objB();
objB.DownloadFile(handler);
}
}).start();
...
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case Constants.HANDLER_MESSAGE_PERFORM_DIALOG_UPDATE:
progress.setProgress(msg.arg1);
break;
default:
Log.w("TAG_NAME","handleMessage / Message type not recognised / msg.what = "+String.valueOf(msg.what));
}
}
};
}
Class B
{
public void DownloadFile(Handler handler)
{
... some work [preparing SOAP request]
while(response.read())
{
//send calculated progress to Class A to update the progress value
sendMessage(handler,HANDLER_MESSAGE_PERFORM_DIALOG_UPDATE,progress);
}
}
private void sendMessage(Handler handler,int what, int arg1){
Message msg = Message.obtain();
msg.what = what;
msg.arg1 = arg1;
handler.sendMessage(msg);
}
}
Я всегда использую этот вид pattre и работает gr8 для меня...
class A{
new Thread(new Runnable()
{
public void run()
{
B objB = new B(new ListnerClass());
objB.DownloadFile();
}
}).start();
class ListnerClass implements B.ValueListner{
update(int v){
doWork();
}
}
}
class B{
ValueListner listner;
interface ValuListner{
update(int i);
}
B(ValueListner listner){
this.listner = listner;
}
public void DownloadFile()
{
... some work [preparing SOAP request]
while(response.read())
{
listner.update(value);
}
}
}