I have a code running inside the Thread. I tried to use the handler to do receive the message from the thread so i can update the UI. Unfortunately, the message didn't get send to the handler.
This is my code snippet inside the run method of the Thread
ChromaticLayout chromatic = new ChromaticLayout(mPartition, mDeviceWidth, mDeviceHeight, mData);
chromatic.execute(new ChromaticLayout.LayoutCallback() {
#Override
public synchronized void retrieveResult(Object[][] data) {
// TODO Auto-generated method stub
mPhotoData.clear();
Log.w("CALLBACK", "start");
for (int i=0; i<data.length; i++)
{
PhotoFrameData[] row = new PhotoFrameData[data[i].length];
for (int j=0; j<data[i].length; j++) {
if (j==0)
Log.w("CALLBACK", "Width = " + ((PhotoFrameData) data[i][j]).getRectangle().width() + " height = " + ((PhotoFrameData) data[i][j]).getRectangle().height() );
row[j] = (PhotoFrameData) data[i][j];
}
mPhotoData.add(row);
}
Log.w("CALLBACK", "end");
PhotoFrameAdapter.this.handle.post(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
PhotoFrameAdapter.this.handle.sendEmptyMessage(1);
} });
//if (!PhotoFrameAdapter.this.handle.sendEmptyMessage(1))
// Log.w("CALLBACK", "Handle not working");
}});
}
The is the receiving message of the handler:
protected Handler handle = new Handler() {
public void handleMessage(Bundle message) {
//PhotoFrameAdapter.this.notifyDataSetChanged();
mListener.dataLoaded(this);
}
};
What make it not adding to the message queue and call the handleMessage? Thanks
try this:
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
//do staff
break;
}
};
};
Another way you can use a Handler is as follows (it's perhaps a simpler implementation in many cases):
Define the hander on the UI thread:
private Handler mHandler = new Handler();
Then from your background thread just post a Runnable with the code you want to run:
mHandler.post(new Runnable() {
#Override
public void run() {
// Code to run here
}
});
Related
i want to do some stuff on every few seconds in my app, for that purpose , i have implemented HandlerThread & handler via following code
handlerThread = new HandlerThread(getClass().getSimpleName());
handlerThread.start();
handler = new Handler(handlerThread.getLooper(), new Callback() {
#Override
public boolean handleMessage(Message msg) {
//my code here
return l.this.handleMessage(msg);
}
});
I initiate this handler by sending message from onCreate()
I handle the message as follows :
private boolean handleMessage(Message msg) {
switch (msg.what) {
default:
return false;
case MY_MESSAGE:
if(handler_stop==0)
{
checkLauncher();
sendMessage(MY_MESSAGE); // I Send the message from here to make //this continuous
}
}
return true;
}
It's Working fine but it Sends message too fast , i mean constantly , instead i want this message to be sent after 2 or 3 seconds , In Short , i want to repeat task every 2-3 seconds.
How can i do this on above code ? please some one help
First declare one global varialbe for Handler to update the UI control from Thread, like below:
Handler mHandler = new Handler();
Now create one Thread and use while loop to periodically perform the task using the sleep method of the thread.
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(10000);// change the time according to your need
mHandler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
// Write your code here to update the UI.
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
Else just add this in your code:
handler.postDelayed(new Runnable(){
public void run() {
// do something
}}, 20000);
Why not to use Handler.sendMessageDelayed? It allows you to schedule your message to be delivered to the Handler with delay that you specify. So your code will look like this:
private boolean handleMessage(Message msg) {
switch (msg.what) {
default:
return false;
case MY_MESSAGE:
if(handler_stop == 0) {
checkLauncher();
sendMessageDelayed(MY_MESSAGE, 2000); // Send message everytime with 2 seconds delay
}
}
return true;
}
hi i have an simple way for doing this
try this
Runnable runnable;
final Handler handler = new Handler();
runnable = new Runnable() {
public void run() {
// HERE I AM CHANGING BACKGROUND YOU CAN DO WHATEVER YOU WANT
_images[i].setBackgroundResource(imageArray[0]);
i++;
handler.postDelayed(this, 1000); // for interval...
}
};
handler.postDelayed(runnable, 1000); // for initial delay..
worked for me hope you will also find it working
thanks
Vote Up if find usefull.
I have an application which starts a new service. In this service I currently have a handler that does some work every minute and then sends the results to the main activity through a BroadcastReceiver. I want the following thing: Every minute create a new thread inside the service, make it do the work and send a message to the handler that it is finnished and then the handler will send to the main activity through a BroadcastReceiver. How can i combine the Thread and the Handler? Here is what I have so far -only part of code of interest-
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
try {
getAppResources(); //this is the work i want to place in a new thread
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
intent.putExtra(key,value);
sendBroadcast(intent);
handler.postDelayed(this, 60*1000);
}
};
Here is what i understand i need to do
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
/* try {
getAppResources();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
Thread t = new Thread() {
#Override
public void run(){
try {
getAppResources();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendEmptyMessage(0);
}
};
handler.postDelayed(this, 60*1000);
}
};
And where do i place the handleMessage ? If i place it inside the Runnable it says it is never used locally. I just place it right before the Runnable ?
public void handleMessage(Message msg){
if(msg.what == 0){
intent.putExtra(key,value);
sendBroadcast(intent);
}
}
Is this how I should do it ?
EDIT: Handler code that sends to the main activity some data
private final Handler handler = new Handler(){
public void handleMessage(Message msg){
if(msg.what == 0){
Log.d("HANDLE","Am primit mesaj");
//Notify preparations
intent.putExtra("RunningApps", runningApps.size());
intent.putExtra("CPU", highestDrainPackageCPU);
intent.putExtra("GPS",highestDrainPackageGPS);
intent.putExtra("WIFI", highestDrainPackageWIFI);
//Now i have all my data, time to send them to the activity
//First , send the strings to be set in the TextViews
//Each running app has 7 messages to display -> ArrayList<String>
for(int i=0;i<runningApps.size();i++){
intent.putStringArrayListExtra(String.valueOf(i), appInfo.get(i));
}
//Next send values to plot the chart
//CPU energy consumption for highest draining application
double [] currValues_cpu = new double[tableCPU.get(highestDrainPackageCPU).size()];
Log.d("CPUSIZE",String.valueOf(currValues_cpu.length));
for(int j=0;j<tableCPU.get(highestDrainPackageCPU).size();j++){
currValues_cpu[j]=tableCPU.get(highestDrainPackageCPU).get(j);
Log.d("CPUVALUE",String.valueOf(currValues_cpu[j])+"For application"+highestDrainPackageCPU);
}
intent.putExtra("highestDrainPackageCPU", currValues_cpu);
//GPS energy consumption for highest draining application
double [] currValues_gps = new double[tableGPS.get(highestDrainPackageGPS).size()];
for(int j=0;j<tableGPS.get(highestDrainPackageGPS).size();j++){
currValues_gps[j]=tableGPS.get(highestDrainPackageGPS).get(j);
}
intent.putExtra("highestDrainPackageGPS", currValues_gps);
//WIFI energy consumption for highest draining application
double [] currValues_wifi = new double[tableWIFI.get(highestDrainPackageWIFI).size()];
for(int j=0;j<tableWIFI.get(highestDrainPackageWIFI).size();j++){
currValues_wifi[j]=tableWIFI.get(highestDrainPackageWIFI).get(j);
}
intent.putExtra("highestDrainPackageWIFI", currValues_wifi);
sendBroadcast(intent);
}
}
};
Here is the BroadcastReceiver in the Main Activity and the UpdateUI function:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
public void updateUI(Intent intent){
resourceTab.removeAllViews();
//statisticsTab.removeAllViews();
int apps_no = intent.getIntExtra("RunningApps", 0);
String highestDrainPackageCPU = intent.getStringExtra("CPU");
String highestDrainPackageGPS = intent.getStringExtra("GPS");
String highestDrainPackageWIFI = intent.getStringExtra("WIFI");
//TO-DO: Get information for each app and store it in textview.Then add it to a linearlayout
for(int i=0;i<apps_no;i++){
//Setup delimiter
View delimitator = new View(this);
delimitator.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,1));
delimitator.setBackgroundColor(Color.parseColor("#50FFFFFF"));
//Extract values
ArrayList<String> info = new ArrayList<String>();
info=intent.getStringArrayListExtra(String.valueOf(i));
for(int j=0;j<info.size();j++){
TextView infoApp = new TextView(this);
//////Setup textview//////////
infoApp = new TextView(this);
infoApp.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
infoApp.setTextColor(Color.parseColor("#FFFFFF"));
infoApp.setText(info.get(j));
resourceTab.addView(infoApp);
}
//Add delimiter
resourceTab.addView(delimitator);
}
double [] cpu_values = intent.getDoubleArrayExtra("highestDrainPackageCPU");
double [] gps_values = intent.getDoubleArrayExtra("highestDrainPackageGPS");
double [] wifi_values = intent.getDoubleArrayExtra("highestDrainPackageWIFI");
//Now plot the graph
createGraphOverall(cpu_values, gps_values, wifi_values, highestDrainPackageCPU, highestDrainPackageGPS, highestDrainPackageWIFI);
//Update the table
updateTable(cpu_values, gps_values, wifi_values, highestDrainPackageCPU, highestDrainPackageGPS, highestDrainPackageWIFI);
}
My Activity was successfully updated before I tried to create a new thread to do the heavy work inside the service.
EDIT: Sorry, I think I noticed it earlier, and got side tracked with the handler.
You create Thread t, but you never run it.
t.start();
You define handleMessage() as a method of the handler, like this:
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
//TODO: Handle different types of messages
}
};
I want to write a download manager app, in the activity I add a progress bar which show the current progress to the user, now if user touch the back button and re-open the activity again this ProgressBar won't be updated.
To avoid from this problem I create a single thread with unique name for each download that keep progress runnable and check if that thread is running in onResume function, if it is then clone it to the current thread and re-run the new thread again but it won't update my UI either, Any ideas !?
#Override
public void onResume()
{
super.onResume();
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
for (int i = 0; i < threadArray.length; i++)
if (threadArray[i].getName().equals(APPLICATION_ID))
{
mBackground = new Thread(threadArray[i]);
mBackground.start();
downloadProgressBar.setVisibility(View.VISIBLE);
Toast.makeText(showcaseActivity.this
, "Find that thread - okay", Toast.LENGTH_LONG).show();
}
}
private void updateProgressBar()
{
Runnable runnable = new updateProgress();
mBackground = new Thread(runnable);
mBackground.setName(APPLICATION_ID);
mBackground.start();
}
private class updateProgress implements Runnable
{
public void run()
{
while (Thread.currentThread() == mBackground)
try
{
Thread.sleep(1000);
Message setMessage = new Message();
setMessage.what = mDownloadReceiver.getProgressPercentage();
mHandler.sendMessage(setMessage);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
catch (Exception e)
{/* Do Nothing */}
}
}
private Handler mHandler = new Handler()
{
#Override
public void handleMessage(Message getMessage)
{
downloadProgressBar.setIndeterminate(false);
downloadProgressBar.setProgress(getMessage.what);
if (getMessage.what == 100)
downloadProgressBar.setVisibility(View.GONE);
}
};
Download button code:
downloadBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
downloadProgressBar.setVisibility(View.VISIBLE);
downloadProgressBar.setIndeterminate(true);
downloadProgressBar.setMax(100);
Intent intent = new Intent(showcaseActivity.this, downloadManagers.class);
intent.putExtra("url", "http://test.com/t.zip");
intent.putExtra("receiver", mDownloadReceiver);
startService(intent);
updateProgressBar();
}
});
I'd strongly recommend reading the Android Developer blog post on Painless Threading. As it states, the easiest way to update your UI from another thread is using Activity.runOnUiThread.
I am trying to load an object from a server in Android. This object is loaded in a thread. When loading is finished, an _objectHandler is called to get some key - values from the object, for example, the _filename key. Every time a filename is retrieved, I want to display it. For this reason, I am looping over the element of the loaded object in a second thread, and calling a _handler every time a value is loaded. What I want to get is all the _filename values, but what I am getting is only the last value of the _fielName. what I am doing wrong?
ArrayList <myObject> object;
String filename;
Thread thread = new Thread (MyActivity.this);
thread.start();
public void run() {
Looper.prepare();
try {
object = getObjectFromServer();
} catch (Exception e) {
e.printStackTrace();
}
_objectHandler.sendEmptyMessage(0);
Looper.loop();
}
Handler _objectHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
for (int i = 0; i < object.size(); i++) {
myObject obj= object(i);
new Thread(new Runnable() {
public void run() {
filename= obj.getFileName();
Message msg = new Message();
_handler.sendEmptyMessage(0);
}
}).start();
}
}
};
Handler _handler = new Handler() {
#Override
public void handleMessage(Message msg) {
Log.i("The fielname is ", " filename" + filename
}
};
you can use android.os.Handler class. This will provide you a mechanism for enqueue an action to be performed on a different thread than your own.
Consider i have one thread as a separate class , for example SimpleThread.java,
class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
}
}
from my android home.java i need to start the thread,
new SimpleThread("Jamaica").start();
once the loop end i need to shoe the alert,but when i use
authalert = new AlertDialog.Builder(this);
it shows null pointer execption, i need a context over here in thread class , is there any other way to do this.
Hey you should use Handler for this
here is the code ...
ProgressDialog _progressDialog = ProgressDialog.show(this,"Saving Data","Please wait......");
settintAdater();
private void settingAdater(){
Thread _thread = new Thread(){
public void run() {
Message _msg = new Message();
_msg.what = 1;
// Do your task where you want to rerieve data to set in adapet
YourCalss.this._handle.sendMessage(_msg);
};
};
_thread.start();
}
Handler _handle = new Handler(){
public void handleMessage(Message msg) {
switch(msg.what){
case 1:
_progressDialog.dismiss();
listview.setAdapter();
}
}
}
One way of solving your problem is using Handlers, as Sujit suggested. Other way is using AsyncTask. Read here.
the problem is : when you launch the thread, the Compiler will not wait until the thread finish his treatement , he will execute the next instruction ( authalert = new AlertDialog.Builder(this); )
so there are two or three ways to do this :
1) , use handler
2) define your own listener for your thread in order to listen until he finished his treatement ,
3) you can pass the Context of your activity , and at the last line of your run method , display the AlertDialog ( with Activity.runOnUiThread(new Runnable); )
You should read http://www.aviyehuda.com/2010/12/android-multithreading-in-a-ui-environment/ and http://developer.android.com/resources/articles/painless-threading.html
one way would be put a handler in your calling activity:
final mContext=this;
final Handler mHandler=new Handler(){
#Override
public void handleMessage(Message msg) {
int yourIntReturnValue=msg.what;
//cast your object back to whatever it was lets say it was a string:
// String yourString=(String) msg.obj;
//do something like authalert = new AlertDialog.Builder(mContext);
}
};
then
class SimpleThread extends Thread {
Handler mHandler;
public SimpleThread(String str, Handler h) {
super(str);
mHandler=h;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
Message.obtain(mHandler, someIntRetValue,
"DONE" ).sendToTarget();
}
}