How can I put Toast in a Runnable of a Service? - android

I have a service which contains a Timer and TimerTask for receiving data from Webservice in periods of time. everything works fine except Toast. I want to show a Toast to user in procSendMapMovements but i get exception. How can I use Toast in it?
class taskSendMapMovements extends TimerTask {
#Override
public void run() {
hhSendMapMovements.sendEmptyMessage(0);
}
};
// /////////////////////
final Runnable rSendMapMovements = new Runnable()
{
public void run()
{
procSendMapMovements();
}
};
final Handler hhSendMapMovements = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
performOnBackgroundThread(rSendMapMovements);
return false;
}
});
// /////////////////////
public void procSendMapMovements() {
try {
Toast.makeText(SrvDataExchange.this,
"some texts"
Toast.LENGTH_SHORT).show();
// exception here
// my process
} catch (Exception e) {
}
}
#Override
public void onStart(Intent intent, int startId) {
try {
timerSendMapMovements = new Timer();
timerSendMapMovements
.schedule(new taskSendMapMovements(),
10*60*1000,
10*60*1000);
//
} catch (NumberFormatException e) {
Toast.makeText(this, "error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
#Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}

Create a handler to display toast.
Use following:
where you want to display toast call:
//printToast.sendEmptyMessage();//If you dont want to send no paramter
//if you want to send some object to handler
/*
Message msg=printToast.obtainMessage();
msg.obj=objToSent;
printToast.sendMessage(msg);
*/
final Handler printToast= new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
Toast.makeText....;
}
});

**
Handler printToast= new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
Toast.makeText....;
}
});
your Runnable
{
run()
{
do what ever you want
printToast.sendMessage(printToast.obtainMessage());
}
}
**

Related

How to use a HandlerThread to juggle 2 Threads

I have a class that extends HandlerThread and implements Handler.Callback. I can't understand how to setup the Handlers to send messages back and forth to each other under this scheme. My Handler1 needs to talk to Handler2 and vice versa but because this is being implemented in a HandlerThread which has it's own looper I am not sure how to instantiate these objects. I'm simply stuck on how to apply this to syntax. I have posted my crack at it below. Any help is appreciated.
...
public class MyClass implements Runnable {
private Handler handler1 = null;
private Handler handler2 = null;
CyclicBarrier barrier = new CyclicBarrier(2);
class myThread extends HandlerThread implements Handler.Callback {
...
#Override
protected void onLooperPrepared() {
handler1 = new Handler(getLooper(), this){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
}
};
handler2 = new Handler(getLooper(), this){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
}
};
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
Runnable runnable1 = new Runnable(){
#Override
public void run() {
Message message = Message.obtain();
message.setTarget(handler2);
message.obj = handler2;
message.sendToTarget();
}
};
Runnable runnable2 = new Runnable(){
#Override
public void run() {
Message message = Message.obtain();
message.obj = handler1;
message.setTarget(handler1);
}
};
}
#Override
public boolean handleMessage(Message reqMsg) {
//do some work
return true;
}
}
...
public void run() {
Thread mThread1 = new Thread(runnable1);
Thread mThread2 = new Thread(runnable2);
mThread1.start();
mThread2.start();
}
}
Here is the refactored code:
public class MyClass implements Runnable
{
private Handler handler1 = null;
private Handler handler2 = null;
CyclicBarrier barrier = new CyclicBarrier(2);
class myThread extends HandlerThread implements Handler.Callback
{
public myThread(String sName)
{
super(sName);
}
#Override
protected void onLooperPrepared() {
handler1 = new Handler(getLooper(), this){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
}
};
handler2 = new Handler(getLooper(), this){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
}
};
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public boolean handleMessage(Message reqMsg) {
//do some work
return true;
}
}
Runnable runnable1 = new Runnable(){
#Override
public void run() {
Message message = Message.obtain();
message.setTarget(handler2);
message.obj = handler2;
message.sendToTarget();
}
};
Runnable runnable2 = new Runnable(){
#Override
public void run() {
Message message = Message.obtain();
message.obj = handler1;
message.setTarget(handler1);
}
};
public void run() {
Thread mThread1 = new Thread(runnable1);
Thread mThread2 = new Thread(runnable2);
mThread1.start();
mThread2.start();
}
}
}

Possible Android Thread Bug - Custom Listener

please see the codes:
MainActivity.java:
protected void onCreate(Bundle savedInstanceState) {
...
TestClass tc = new TestClass();
tc.Test(new TestListener() {
public void onSuccess() {
//success do something
}
public void onFail() {
//fail do something
}
});
}
TestClass:
public class TestClass {
private static final int MSG_SUCCESS = 1;
private static final int MSG_FAIL = 0;
private TestListener listener = null;
public void Test(TestListener listener) {
this.listener = listener;
Log.d("test", "=======" + Thread.currentThread().getId());
HandlerThread ht = new HandlerThread("MyThread");
ht.start();
Thread thread = new Thread(mRunnable);
thread.run();
}
#SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SUCCESS:
Log.d("test", "on success");
if (listener != null) {
listener.onSuccess();
}
break;
case MSG_FAIL:
if (listener != null) {
listener.onFail();
}
break;
}
}
};
Runnable mRunnable = new Runnable() {
#Override
public void run() {
Log.d("test", "=======" + Thread.currentThread().getId());
try {
Log.d("test", "start sleep");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("test", "sleep end");
mHandler.obtainMessage(MSG_SUCCESS).sendToTarget();
}
};
}
TestListener:
public interface TestListener {
public void onSuccess();
public void onFail();
}
print log:
07-30 15:15:03.565: D/test(2202): =======1
07-30 15:15:03.565: D/test(2202): =======1
Slaver Thread have no effect??
This is the problem:
thread.run();
That's running the Runnable code synchronously, in the existing thread. You meant:
thread.start();
first of all you will have to show() your Toast msgs:
Toast.makeText(getApplicationContext(), "onsuccess", Toast.LENGTH_SHORT).show();
and you want to start() your thread:
thread.start();

Android Task AsyncTask issue with postExec

the Problem I am having is that the PostExecute is not firing.
I see the log tag for background but P.E. never fires.
I am invoking this task from a timer like this:
findViewById(R.id.buttonstart).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
openFile("FeedTimerTask.html");
Timer t = new Timer("FeedTimerTask", true);
timerTask = new FeedTimerTask();
t.schedule(timerTask, 2000, 20000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Runnable runme = new Runnable() {
#Override
public void run() {
timestart = Calendar.getInstance().getTimeInMillis();
provider.refreshNoCache();
}
};
class FeedTimerTask extends TimerTask{
#Override
public void run() {
try{Looper.prepare();}catch(Exception e){};
runme.run();
}
}
Here is the main task itself from inside the dataprovider class invoked with "provider.refreshNoCache();" above:
// threaded rteftesh tasks
#SuppressWarnings("rawtypes")
public class RefreshTask extends SupportAsyncTask {
private int errorcodecode = 0;
private ProgressDialog dialog=null;
private Exception mainExeption=null;
protected String waitMessage = "Laddar ner information..";
private boolean useCache;
public RefreshTask(boolean useCache) {
this.useCache = useCache;
}
public void onPreExecute() {
data = null;
if (showSpinnerOnRefresh){
dialog = ProgressDialog.show(context, "", waitMessage , true);
dialog.show();
}
}
protected Object doInBackground(Object... params) {
errorcodecode = 1;
try {
invokeFeedRead();
Log.e("DataProvider", "Bkgtask...");
errorcodecode = 0;
} catch (BrJSONException e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 1;
} catch (IOException e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 2;
} catch (Exception e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 3;
}
if (errorcodecode==0){
}
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
Log.e("DataProvider", "Cancelled...");
if (dialog != null)
try{dialog.dismiss();}catch(Exception e){}
BrAlert.Show(context, "Obs", BrAppConfig.ServerError+" (timeout)", 0);
onError_IO(new IOException("Timeout!"));
errorcodecode=2;
}
#Override
protected void onPostExecute(Object result) {
// super.onPostExecute(result);
Log.e("DataProvider", "PostExec...");
if (dialog != null)
try{dialog.dismiss();}catch(Exception e){}
switch (errorcodecode) {
case 0:
onFeedLoaded();
cacheAge = System.currentTimeMillis();
break;
case 1:
onError_DataFormat(mainExeption);
break;
case 2:
onError_IO(mainExeption);
break;
default:
onError_GeneralExeption(mainExeption);
}
}
}
Your task is cancelled even before it reached onPostExecte method. If the task is cancelled before it reaches onPostExecute Method. It will not trigger onPostExecute but trigger onCancelled Method. Please provide enough time to finish the task.
I found out the problem in the end. It was to do with the scope.
I needed a handler to invoke the other thread.
Here is the solution for others may find helpful:
in on create:
tickHandler = new Handler();
tickTimer = new Timer();
tickTimer.schedule(new FeedTimerTask(),
0,
50000); //FPS
The handler class.
class FeedTimerTask extends TimerTask{
private Runnable runable;
public FeedTimerTask(){
super();
runable = new Runnable(){
#Override
public void run() {
timestart = Calendar.getInstance().getTimeInMillis();
provider.refreshNoCache();
}
};
}
#Override
public void run() {
tickHandler.post(runable);
}
}

How can I prevent UI hang, when my service runs a TimerTask?

I have a service which contains a Timer and TimerTask for receiving data from Webservice in periods of time. When my TimerTask runs, the UI hangs until the Webservice process complete. How can I put my task in a thread to prevent the UI hanging?
My code:
Timer timerSyncFull = new Timer();
class taskSyncFull extends TimerTask {
#Override
public void run() {
hSyncFull.sendEmptyMessage(0);
}
};
final Handler hSyncFull = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
procSyncFull();
return false;
}
});
public void procSyncFull() {
try {
// My webservice process
} catch (Exception e) {
}
}
#Override
public void onStart(Intent intent, int startId) {
timerSyncFull = new Timer();
timerSyncFull.schedule(new taskSyncFull(), 5*60*1000,
5*60*1000);
}
Use AsyncTasks or attach your Handler to another Looper thread.
I used the following code and my problem solved:
class taskSendMapMovements extends TimerTask {
#Override
public void run() {
hhSendMapMovements.sendEmptyMessage(0);
}
};
// /////////////////////
final Runnable rSendMapMovements = new Runnable()
{
public void run()
{
procSendMapMovements();
}
};
final Handler hhSendMapMovements = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
performOnBackgroundThread(rSendMapMovements);
return false;
}
});
// /////////////////////
public void procSendMapMovements() {
try {
showToast("some text");
//My Main Process
} catch (Exception e) {
}
}
#Override
public void onStart(Intent intent, int startId) {
try {
timerSendMapMovements = new Timer();
timerSendMapMovements
.schedule(new taskSendMapMovements(),
10*60*1000,
10*60*1000);
//
} catch (NumberFormatException e) {
Toast.makeText(this, "error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
final Handler hToast = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
Toast.makeText(SrvDataExchange.this,
msg.getData().getString("msg"),
Toast.LENGTH_LONG).show();
return false;
}
});
private void showToast(String strMessage) {
Message msg = new Message();
Bundle b = new Bundle();
b.putString("msg", strMessage);
msg.setData(b);
hToast.sendMessage(msg);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
#Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
Simply invoke your procSyncFull() method in thread or asyncTask.
final Handler hSyncFull = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
Thread thread=new Thread()
{
public void run(){
procSyncFull();
}
}
return false;
}
});
private Handler webserviceCompletionHandler=new Handler()
{
#Override
public boolean handleMessage(Message msg) {
return false;
}
};
use AsyncTask carry out your execution in doInBackground() and populate it in onPostExecute()
AsyncTask Example

Implement a Thread by providing a new class that extends Thread and overriding its run() method

Implementing a Thread by providing a new class that extends Thread and overriding its run() method is new to me. I've tried all day to get it to work. Here's my code:
/*
* see http://developer.android.com/reference/java/lang/Thread.html
*/
class threadClass extends Thread {
private Handler mHandler;
private Message mMsg;
// constructor
public threadClass(Handler handler, Message msg) {
// do something like save the Handler reference
mHandler = handler;
mMsg = msg;
}
#Override
public void run() {
// do some background processing, call the Handler?
mHandler.sendMessage(mMsg);
}
}
public Thread passHandlerToThread(Handler handler) {
handler.sendEmptyMessage(10);
Message msg = Message.obtain();
msg.what = 10;
Thread thread = new threadClass(handler, msg);
return thread;
}
private Handler localHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
int what = msg.what;
if (what == 10) Log.i("localHandler", "what: " + what);
}
};
public void startThread() {
Thread thread = passHandlerToThread(localHandler);
thread.start();
}
I call startThread() in my LocalService onCreate() but nothing happens. What am I doing wrong? I was expecting localHandler() to be called twice: once in passHandlerToThread() and again in run().
Do something like this:
private final Handler handler = new Handler();
// toast runnables
final Runnable updateTwitterNotification = new Runnable() {
#Override
public void run() {
dismissProgressSpinner();
Toast.makeText(getBaseContext(), "Tweet sent!", Toast.LENGTH_LONG).show();
}
};
final Runnable updateCreateError = new Runnable() {
#Override
public void run() {
Toast.makeText(getBaseContext(), "Tweet error!", Toast.LENGTH_LONG).show();
}
};
postMessageInThread();
//implementation:
private void postMessageInThread() {
Thread t = new Thread() {
#Override
public void run() {
try {
connectToTwitterService() // or whatever
handler.post(updateTwitterNotification);
} catch (Exception ex) {
Log.e(TAG, "Error sending msg", ex);
handler.post(updateCreateError);
}
}
};
t.start();
}

Categories

Resources