I have a method written in a main thread(UI thraed) in android service. In tht method I created a handler class like below
public void myMethod(){
public Handler _handler = new Handler(){
public void handleMessage(Message msg){
Log.v("LOG_TAG", "value of msg===>"+msg);
}
};
My question is how to call _handler object in another thread so that I can get data to handler class.
Thanks
Try,
public void myMethod(){
Handler _handler = new Handler(Looper.getMainLooper()){
public void handleMessage(Message msg){
// Call your method of UI thread here... it will work.
Toast.makeText(context, "UI test", Toast.LENGHT_SHORT).show();
Log.v("LOG_TAG", "value of msg===>"+msg);
}
};
_handler.sendEmptyMessage(0);
}
and one more alternative:
public void myMethod(){
Handler _handler = new Handler(Looper.getMainLooper());
_handler.post(new Runnable() {
// Call your method of UI thread here... it will work.
Toast.makeText(context, "UI test", Toast.LENGHT_SHORT).show();
});
}
and if you not able to call your ui methods inside myMethod (not in scope) then see:
https://stackoverflow.com/a/14444110/3582473
Related
I have a handler for a thread in my MainActivity that calls a method named UpdateGUI.
Both the handler/thread declaration and the method are within the MainActivity.
This is the handler Declaration:
Handler handlerData = new Handler();
private Runnable runnableCode2 = new Runnable() {
#Override
public void run() {
Log.d("Handlers","GET TOTAL RX BYTES: "+Long.toString(res) );
//Some code here that doesn't matter/
UpdateGUI();
}
handlerData.postDelayed(runnableCode2, 1*6000);
}
};
And UpdateGUI is as follows:
public void UpdateGUI(){
Log.d("Updater", "STARTING UPDATE");
//Code that doesn't matter here}
}
From the logger I can see that UpdateGUI() is not being called from the thread. Can you explain why this is happening and how it can be fixed?
Just to clarify. The thread is running,but for some reason it doesn't make the call to UpdateGUI().
You need to atleast run handler once then only it will continuously called from the handler runnable method.
so call handler.post(runnableCode2); once in your code and that will be repeated
handlerData.postDelayed(runnableCode2, 1*6000);
hope this will resolved your issue.
I cant see you starting the Runnable.
Handler handlerData = new Handler();
private Runnable runnableCode2 = new Runnable() {
#Override
public void run() {
Log.d("Handlers","GET TOTAL RX BYTES: "+Long.toString(res) );
//Some code here that doesn't matter/
UpdateGUI();
}
handlerData.postDelayed(runnableCode2, 1*6000);
}
};
// This part is missing
handlerData.postDelayed(runnableCode2, 1000);
I want to make downloader, which download data and then call function in UI thread. I have this in main activity
onCreate(){
...
dataRepository.downloadIfNewOrEmpty(new DownloadResponse() {
#Override
public void SuccessResponse(Response response) {
// do something in UI
}
});
}
My function downloadIfNewOrEmpty looks for now only simple with sleep()
public void downloadIfNewOrEmpty(final DownloadResponse response){
//final Handler handler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
response.SuccessResponse(ResponseCode.SUCCESS);
/*handler.post(new Runnable() {
#Override
public void run() {
response.SuccessResponse(ResponseCode.SUCCESS);
}
});*/
}catch (Exception e){
// Log...
}
}
}).start();
}
If I run this code, it normally does the job and update my UI. I found this solution with Handler (android.os.Handler) but if I run it without or with Handler (commented version) it works same.
Although without handler function SuccessResponse is run in UI thread?
Thank you
Although without handler function SuccessResponse is run in UI thread?
Yes, because response is instance of DownloadResponse which is passed from UI Thread as parameter to downloadIfNewOrEmpty.
In the last days I have found myself using this approach for asynchronously performing some long operation (several seconds), and then return some value via a callback that must execute on the caller thread, which is typically but not necessarily the UI thread.
public abstract class DoSomethingCallback
{
public abstract void done(Object result);
}
public void doSomething(final Object param, final DoSomethingCallback doSomethingCallback)
{
// Instantiate a handler for the calling thread
final Handler handler = new Handler();
// Start running the long operation in another thread
new Thread(new Runnable() {
#Override
public void run() {
// Do a long operation using "param" as input...
Object result = longOperation(param);
// Return result via a callback, which will run in the caller thread
handler.post(new Runnable() {
#Override
public void run() {
doSomethingCallback.done(clearBytes);
}
});
}
}).start();
}
This seems to work pretty well and is very simple to use. However, I somehow suspect it might have some problems I'm not aware of. So the question is, what are the potential issues of this approach? What are better alternatives than manually creating and running a thread? I'm seeking for simplicity and robustness.
The only problem is that such approach breaks encapsulation: the second thread not only computes the result, but also dictates what the caller thread should do with it. So I'd better refactor your code as follows:
public abstract class DoSomethingCallback {
final Handler handler = new Handler();
public void post(final Object result) {
handler.post(new Runnable() {
#Override
public void run() {
doSomethingCallback.done(result);
}
});
}
public abstract void done(Object result);
}
public void doSomething(final Object param, final DoSomethingCallback doSomethingCallback) {
// Instantiate a handler for the calling thread
final DoSomethingCallback handler = new DoSomethingCallback () {
void done(Object result) {
...
}
};
// Start running the long operation in another thread
new Thread(new Runnable() {
#Override
public void run() {
// Do a long operation using "param" as input...
Object result = longOperation(param);
// Return result via a callback, which will run in the caller thread
handler.post(result);
});
}
}).start();
}
When I run the application with eclipse it shows me an error: "can't create handler inside thread that hos not called looper.prepare()" and I do not understanding why.
This is a part of my code
public void execute_web_service() {
progressd = ProgressDialog.show(liste_voyage.this, "", "Chargement...", true,
false);
Thread thread = new Thread(liste_voyage.this);
thread.start();
}
public void run() {
get_liste_arrives();
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
progressd.dismiss();
afficher_liste_arrives();
}
};
You will get this error, with the above code, if the code that is creating an instance of this class is running on a thread other than the main application thread.
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
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);
}
}
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);
}
}
}
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);
});
}