How to pass progress value from thread to activity

2019-04-07 15:51发布

I am having a design issue sending progress bar value from class called from a Thread in Activity class to update the GUI, as the following

[The code snippet don't compile it's for explaining only]:

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
       }

    }

}

Any help or guide would be greatly appreciated

3条回答
女痞
2楼-- · 2019-04-07 16:23

You could make an updateProgressBar method in class A and then pass class B a reference to class A. Class B could then call the callback function in A (probably pass an int or something to indicate how far the progress is). Updating the UI from a different thread then the UI thread tends to cause problems. Luckily the Activity class has the method "runOnUiThread(Runnable action)". So to set the progress you could do something like:

while(response.read()){
  //do stuff here
int progress = getProgress(); //set the progress to something
  a.runOnUiThread(new Runnable(){
    a.updateProgress(progress);
  });
}
查看更多
叼着烟拽天下
3楼-- · 2019-04-07 16:39

I've used a Handler to achieve this effect. Create it in the Activity that you create the ProgressDialog in, then pass the Handler into the maethod you want to get the progress from. Then you can send a message back to the calling Activity to update the progress:

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);
    }
}
查看更多
我想做一个坏孩纸
4楼-- · 2019-04-07 16:40

I always use this kind of pattre and works gr8 for me...

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);
        }

    }
}
查看更多
登录 后发表回答