thread = new Thread(new Runnable() {
#Override
public void run() {
synchronized (datahandler) {
while (true) {
try {
if (datahandler.getCount() > 0) {
commitData();
}
datahandler.wait();
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("Service", e.toString());
}
}
}
}
});
thread.start();
Commitdata to connect and commit data form datahandler to server. But I dont kow why it shows not respone dialog. If I do not close it, it continouns to commit. Why UI is influenced when I commit data in other thread
public class ThreadsLifecycleActivity extends Activity {
// Static so that the thread access the latest attribute
private static ProgressDialog dialog;
private static Bitmap downloadBitmap;
private static Handler handler;
private ImageView imageView;
private Thread downloadThread;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create a handler to update the UI
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
imageView.setImageBitmap(downloadBitmap);
dialog.dismiss();
}
};
// get the latest imageView after restart of the application
imageView = (ImageView) findViewById(R.id.imageView1);
Context context = imageView.getContext();
System.out.println(context);
// Did we already download the image?
if (downloadBitmap != null) {
imageView.setImageBitmap(downloadBitmap);
}
// check if the thread is already running
downloadThread = (Thread) getLastNonConfigurationInstance();
if (downloadThread != null && downloadThread.isAlive()) {
dialog = ProgressDialog.show(this, "Download", "downloading");
}
}
public void downloadPicture(View view) {
dialog = ProgressDialog.show(this, "Download", "downloading");
downloadThread = new MyThread();
downloadThread.start();
}
// save the thread
#Override
public Object onRetainNonConfigurationInstance() {
return downloadThread;
}
// dismiss dialog if activity is destroyed
#Override
protected void onDestroy() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
dialog = null;
}
super.onDestroy();
}
static public class MyThread extends Thread {
#Override
public void run() {
try {
// Simulate a slow network
try {
new Thread().sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
downloadBitmap = downloadBitmap("http://www.devoxx.com/download/attachments/4751369/DV11");
// Updates the user interface
handler.sendEmptyMessage(0);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
}
//==========================
You can sea in code that handlers are used to post message on GUI thread. further you can read about it over here
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
Also Read This http://android-developers.blogspot.de/2010/07/multithreading-for-performance.html
Related
My splash screen syncronize my app :
When I use :
sd.execute("init_sync", null).get();
My logo (defined in xml) disappear. If I quit .get(), it appears.
Here is my code :
public class SplashScreen extends Activity {
private Context ctx = null;
private Usuario mUser = null;
SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
ctx = this;
prefs = PreferenceManager.getDefaultSharedPreferences(this);
new Handler().post(new Runnable() {
#Override
public void run() {
// Check if user exists
Gson gson = new Gson();
String jsonUser = prefs.getString("usuario", "");
mUser = gson.fromJson(jsonUser, Usuario.class);
if (NetworkUtils.isOnline(ctx)) {
if (mUser != null) {
SyncData sd = new SyncData(ctx);
try {
sd.execute("init_sync", null).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
Intent i = new Intent(SplashScreen.this, LoginActivity.class);
startActivity(i);
}
} else {
if (mUser != null) {
Intent i = new Intent(SplashScreen.this, DashBoard.class);
startActivity(i);
} else {
Toast.makeText(ctx, "Necesita Internet para loguearse", Toast.LENGTH_LONG).show();
finish();
}
}
}
});
}
}
I have several asyncTask that I use to upload pics, and sync MySQL database with my SQLite database. So, I need to wait till all the processes end to know if there is any error.
The thing is I put it in a thread, so that it would not affect UI. Where am I wrong?
When you use get() it causes the UI thread to wait. Don't use get(). You need to override the onPostExecute method in AsyncTask.
private Boolean task1Finished = false;
private Boolean task2Finished = false;
private Boolean task3Finished = false;
//...
SyncData sd1 = new SyncData(ctx) {
#Override
protected void onPostExecute(Object result) {
task1Finished = true;
goToNextActivity();
}
};
SyncData sd2 = new SyncData(ctx) {
#Override
protected void onPostExecute(Object result) {
task2Finished = true;
goToNextActivity();
}
};
SyncData sd3 = new SyncData(ctx) {
#Override
protected void onPostExecute(Object result) {
task3Finished = true;
goToNextActivity();
}
};
try {
sd1.execute();
sd2.execute();
sd3.execute();
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (ExecutionException e) {
e.printStackTrace();
}
//...
private void goToNextActivity() {
if (task1Finished && task2Finished && task3Finished)
// all tasks complete
}
Like #ashishduh says, I was in UI Thread. So I changed:
new Handler().post(new Runnable() {
#Override
public void run() {
....
}
}
by
Runnable sync = new Runnable() {
#Override
public void run() {
....
}
};
Thread t = new Thread(sync);
t.start();
And it solved my problem!
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();
Am new in android .. am trying to implement thread in a android. But am getting error .. I googled and getting answer "AsyncTask", but truly i dont know how to implement
Error message
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
my code
final Thread thread = new Thread(){
#Override
public void run() {
try {
DatabaseHandler dbh = new DatabaseHandler(test.this);
result=dbh.Verify(1);
if(result != ""){
getData();
progress.dismiss();
}
else{
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
Use following code to run in UI thread.
Runnable runnable = new Runnable() {
#Override
public void run() {
handler.post(new Runnable() { // This thread runs in the UI
#Override
public void run() {
DatabaseHandler dbh = new DatabaseHandler(test.this);
result=dbh.Verify(1);
if(result != ""){
getData();
progress.dismiss();
}
else{
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
new Thread(runnable).start();
Seems like you need to create your handler in MainActivity and then pass it further. Like so:
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
}
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);
}
}
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());
}
}
**