I have try to update my TextView in Thread, but not able to do, below code shows my try
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
String add = null;
public void run() {
add = Util.getLocationCityName(String.valueOf(ltlng.latitude),String.valueOf(ltlng.longitude));
handler.post(new Runnable() {
public void run() {
LogUtil.d("add" + add);//i can get the add value
vImei.setText(add);
}
});
}
};
new Thread(runnable).start();
i can able to get the add value which is inside handler but values are not update to my textview, dont know what mistake i have done
Try to init Handler with looper
final Handler handler = new Handler(Looper.getMainLooper());
Also you can try :
private LooperThread mLooperThread;
class LooperThread extends Thread
{
public Handler mHandler;
public void run()
{
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg)
{
vImei.setText(msg.getData().getString("ADD"));
}
};
Looper.loop();
}
}
create Looper :
mLooperThread = new LooperThread();
mLooperThread.start();
and when you need to update :
Bundle bundle = new Bundle();
bundle.putString("ADD", add);
Message msg = Message.obtain();
msg.setData(bundle);
mLooperThread.mHandler.sendMessage(msg);
//Global Initialize
String add = "";// not null
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
add = Util.getLocationCityName(
String.valueOf(ltlng.latitude),
String.valueOf(ltlng.longitude));
handler.post(new Runnable() {
public void run() {
LogUtil.d("add" + add);//i can get the add value
vImei.setText(add);
}
});
}
};
new Thread(runnable).start();
I hope it helps you.. :)
An other solution which solves your problem is the usage of an AsyncTask
AsyncTask<Void, Void, String> asyncTask = new AsyncTask<Void, Void, String>(){
#Override
protected String doInBackground(Void... params) {
// runs on its own thread
return Util.getLocationCityName(
String.valueOf(ltlng.latitude),
String.valueOf(ltlng.longitude));
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// runs on the UI Thread to Update your Views
LogUtil.d("add" + result);
vImei.setText(result);
}
};
asyncTask.execute();
Please try this,
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
String add = null;
public void run() {
add = Util.getLocationCityName(
String.valueOf(ltlng.latitude),
String.valueOf(ltlng.longitude));
runOnUiThread(new Runnable(){
public void run() {
LogUtil.d("add" + add);//i can get the add value
vImei.setText(add);
}
});
}
};
new Thread(runnable).start();
Related
Im pretty new to android and I'm trying to make an imagebutton in android studio that changes images at set inervals. I tried to just use wait and put it into a different thread but that doesn't seem to work. All I want if for the image to change while also still allowing for a mp3 to be played whilst doing so.
Runnable r = new Runnable() {
#Override
public void run()
{
synchronized (this)
{
try
{
wait(1000);
ank.setImageResource(R.drawable.shank2);
wait(1000);
ank.setImageResource(R.drawable.shank3);
wait(1000);
ank.setImageResource(R.drawable.shank4);
wait(1000);
ank.setImageResource(R.drawable.shank5);
}
catch (Exception e) {}
}
}
};
Thread myThread = new Thread(r);
myThread.start();
Simple way:
public void changeImages() {
Handler uiHandler = new Handler();
uiHandler.postDelayed(new Runnable {
#Override
public void run() {
ank.setImageResource(R.drawable.shank1);
}
}, 1000);
uiHandler.postDelayed(new Runnable {
#Override
public void run() {
ank.setImageResource(R.drawable.shank2);
}
}, 2000);
...
}
Better way:
public void changeImages() {
int[] images = new int[] { R.drawable.shank1, R.drawable.shank2 ... }
long delay = 1000;
Handler uiHandler = new Handler();
for (int imageRes : images) {
uiHandler.postDelayed(new Runnable {
#Override
public void run() {
ank.setImageResource(imageRes);
}
}, delay);
delay += 1000;
}
}
The best way
final Handler uiHandler = new Handler();
final Queue<Integer> queue = new LinkedBlockingQueue<>();
void changeImages() {
queue.add(R.drawable.shank1);
queue.add(R.drawable.shank2);
...
loopImages();
}
void loopImages() {
if (!queue.isEmpty()) {
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
ank.setImageResource(queue.poll());
}
}, 1000);
}
}
I am trying to create an example to know how Handlers work. As shown in the code belwo, I created a workerThread that runs for ever and increment the variable i. within the
run() method, i want to pass the value of the incremented variable to a TextView as shown in the body of the Handler class.
The problem is, the line in which there is "new Handler()" and "handler.sendMessage(m)" are marked with red
please let me know how to solve this problem
MainActivity
public class MainActivity extends AppCompatActivity {
private final static String TAG = MainActivity.class.getClass().getSimpleName();
private TextView mtvIncr = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.mtvIncr = (TextView) findViewById(R.id.tvValue);
new WorkerThread().start();
}
Handler handler =new Handler() {//ERROR
#Override
public void handleMessage(Message msg) {
int sentInt = msg.getData().getInt("what");
mtvIncr.setText("r:"+Integer.toString(sentInt));
}
};
class WorkerThread extends Thread {
private int i = 0;
android.os.Handler mHandler = null;
#Override
public void run() {
super.run();
Looper.prepare();
while(true) {
Log.d(TAG, SubTag.bullet("WorkerThread", "i: " + (i++)));
SystemClock.sleep(1000);
Message m = new Message();
Bundle b = new Bundle();
b.putInt("what", i); // for example
m.setData(b);
handler.sendMessage(m);//ERROR
}
}
}
}
Use Message.obtain() to get a Message object
While the constructor of Message is public, the best way to get one of
these is to call Message.obtain() or one of the
Handler.obtainMessage() methods, which will pull them from a pool of
recycled objects.
And use obj attribute msg.obj = b;
obj: An arbitrary object to send to the recipient.
Info from:
https://developer.android.com/reference/android/os/Message.html
Example:
Handler handler =new Handler() {
#Override
public void handleMessage(Message msg) {
int sentInt = ((Bundle)msg.obj).getInt("what");
mtvIncr.setText("r:"+Integer.toString(sentInt));
}
};
class WorkerThread extends Thread {
private int i = 0;
android.os.Handler mHandler = null;
#Override
public void run() {
super.run();
Looper.prepare();
while(true) {
Log.d(TAG, SubTag.bullet("WorkerThread", "i: " + (i++)));
SystemClock.sleep(1000);
Message msg = Message.obtain();
Bundle b = new Bundle();
b.putInt("what", i); // for example
msg.obj = b;
handler.sendMessage(msg);
}
}
}
Robolectric (3.1) should be able to execute runnable posted to the handler.
#Test
public void shouldExecuteRunnable() throws Exception {
final CountDownLatch signal = new CountDownLatch(1);
final boolean[] result = {false};
Runnable runnable = new Runnable() {
#Override
public void run() {
result[0] = true;
signal.countDown();
}
};
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
handler.post(runnable);
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
signal.await(5, TimeUnit.SECONDS);
Assert.assertTrue(result[0]);
}
Test fails on assertion. Am I missing something?
Any help will be appreciated.
#Test
public void shouldExecuteRunnable() throws Exception {
final boolean[] result = {false};
Runnable runnable = new Runnable() {
#Override
public void run() {
result[0] = true;
}
};
ShadowLooper.pauseMainLooper();
Handler handler = new Handler();
handler.post(runnable);
ShadowLooper.runMainLooperOneTask();
Assert.assertTrue(result[0]);
}
Had the same issue,
This fixed it:
ShadowLooper threadShadow = shadowOf(thread.getLooper());
threadShadow.runOneTask();
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();
}
}
}
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();
}