i am trying to make facebook asynchronous non blocking thread in android. due to which our UI is run separate thread but i am unable to do that can any one tell me how to do that.
and If possible pleade give me one example.
Thanks.........
I don't know much about the Facebook but to access to the ui component from the other thread-
public class Dictionary extends Activity{
Handler mhandler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Handler mhandler = new Handler();
SearchThread thread = new SearchThread();
thread.setParent(this);
thread.setHandler(mhandler);
}
public void notifyItemChanged(ArrayList<ListItem> lItems){
//write code relating to ui here
}
private class SearchThread extends Thread{
private Handler handler;
Dictionary parent;
public void setParent(Dictionary parent) {
this.parent = parent;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
#Override
public void run() {
final Runnable mUpdateResults = new Runnable() {
public void run() {
parent.notifyItemChanged(listItems);
}
};
handler.post(mUpdateResults);
}
}
Related
protected void onCreate(Bundle savedInstanceState) {`
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.test_button);
button.setText("before");
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
button.setText("after");
}
}, 2000);
}
I think this solution will not cause a memory leak. According to the answer which gets most votes (How to pause / sleep thread or process in Android?),this will cause a memory leak. what do you think?
To avoid memory leak, handler need to have WeakReference to activity. You can do it like this
private static class MyHandler extends Handler {}
private final MyHandler mHandler = new MyHandler();
public static class MyRunnable implements Runnable {
private final WeakReference<Activity> mActivity;
public MyRunnable(Activity activity) {
mActivity = new WeakReference<>(activity);
}
#Override
public void run() {
Activity activity = mActivity.get();
if (activity != null) {
Button btn = (Button) activity.findViewById(R.id.button);
btn.setBackgroundResource(R.drawable.defaultcard);
}
}
}
private MyRunnable mRunnable = new MyRunnable(this);
public void onClick(View view) {
my_button.setBackgroundResource(R.drawable.icon);
// Execute the Runnable in 2 seconds
mHandler.postDelayed(mRunnable, 2000);
}
Same is also mentioned in https://stackoverflow.com/a/3039718/3812404
I searched for a way to update UI from another thread, and found that the available approach is to use Handler.post(Runnable) as shown in the code snippet below:
public class MyClass extends Activity {
private final Handler myHandler = new Handler();
final Runnable updateRunnable = new Runnable() {
public void run() {
// Update UI
}
};
private OnClickListener buttonListener = new OnClickListener() {
public void onClick(View v) {
new Thread(new Runnable() {
myHandler.post(updateRunnable);
}).start();
}
};
}
Instead can't we use Handler.sendMessage and do the UI updates from main UI thread in handleMessage():
public class MyClass extends Activity {
private final Handler myHandler = new Handler();
private Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what) {
// Do logic here
}
}
};
private OnClickListener buttonListener = new OnClickListener() {
public void onClick(View v) {
new Thread(new Runnable() {
myHandler.sendEmptyMessage(0);
}).start();
}
};
}
I'm sorry if this is a very basic question, however I'm quite confused with the above two approaches.
You need to use runOnUiThread. You can post a runnable which does the UI operation to main thread as follows,
public class Utils {
public static void runOnUiThread(Runnable runnable){
final Handler UIHandler = new Handler(Looper.getMainLooper());
UIHandler .post(runnable);
}
}
Utils.runOnUiThread(new Runnable() {
#Override
public void run() {
// UI updation related code.
}
});
Read more at:
android: update UI from another thread in another class
Updating UI / runOnUiThread / final variables: How to write lean code that does UI updating when called from another Thread
https://developer.android.com/training/multiple-threads/communicate-ui.html
In my project, I want to implement a timer in another thread that counts down the time spent executing a certain method in my application, and do something if it is taking too much time. When executing the MyManager.startCommand() method, the application is freezing and I don't know why since I think I am not doing anything on the UI thread. Is there anything wrong with my code?
I had originally asked this question and was not experiencing an app freeze, so I don't think it's because I'm sleeping the thread: Runnable posted in another runnable not executed.
public class MyManager{
private MyManager sInstance;
private HandlerThread mHandlerThread;
private Handler mHandler;
private Runnable mTimeoutTimer;
public static MyManager getInstance(){
if(sInstance == null){
sInstance = new MyManager();
}
return sInstance;
}
private MyManager(){
mHandlerThread = new HandlerThread("mHandlerThread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mTimeoutTimer = new Runnable() {
#Override
public void run() {
Log.e(“RUNNABLE RUNNING!”);
}
};
public class MyCommand {
private Runnable myRun;
public MyCommand(){
myRun = new Runnable() {
#Override
public void run() {
MyManager.getInstance().startTimeoutTimer();
MyCommand.this.run();
}
};
}
public void execute() {
myRun.run();
}
abstract public void run();
}
private void startTimeoutTimer(){
mHandler.post();
}
public void startCommand(){
new MyCommand().execute();
}
}
And how I'm using a MyCommand object:
MyCommand command =
new MyCommand() {
#Override
public void run() {
//make api call that happens in another thread
}
};
So I am basically trying to create the timeout timer for that API call.
Try this:
Just wrap your first runnable in a Thread.
public class MyManager{
private MyManager sInstance;
private HandlerThread mHandlerThread;
private Handler mHandler;
private Runnable mTimeoutTimer;
public static MyManager getInstance(){
if(sInstance == null){
sInstance = new MyManager();
}
return sInstance;
}
private MyManager(){
mHandlerThread = new HandlerThread();
mHandler = new Handler(mHandlerThread.getLooper());
mTimeoutTimer = new Runnable() {
#Override
public void run() {
Log.e(“RUNNABLE RUNNING!”);
}
};
public class MyCommand {
private Thread th;
private Runnable myRun;
public MyCommand(){
myRun = new Runnable() {
#Override
public void run() {
MyManager.getInstance().startTimeoutTimer();
try {
Thread.sleep(COMMAND_TIMEOUT_MILLIS * 3);
} catch (InterruptedException e) {}
MyCommand.this.execute();
}
};
th = new Thread(myRun);
}
public void execute() {
th.start();
mHandler.postDelayed(mTimeoutTimer);
}
}
private void startTimeoutTimer(){
mHandlerThread.start();
mHandler.postDelayed(mTimeoutTimer);
}
public void startCommand(){
new MyCommand().execute();
}
}
Also you forgot to start the mHandlerThread
private void startTimeoutTimer(){
mHandlerThread.start();
mHandler.postDelayed(mTimeoutTimer);
}
What I want to do is to launch from the MainActivity in a new Thread a procedure that:
1) Makes an Internet call
2) Extract something like a boolean from the response (that represent which AlertDialog to show)
3) Show the correct (depending on the value of the boolean) AlertDialog in the MainActivity
I have no problems in executing first two steps using a Runnable or a AsyncTask but I can't show the alert in MainActivity
I followed different guides but I couldn't reach the solution.
Solved
My MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler=new Handler();
new Thread(new UpdateRunnable(this,mHandler)).start();
/* Other stuff */
}
My Runnable:
public class UpdateRunnable implements Runnable{
private Activity activity;
private Handler mHandler;
private boolean update;
/* Other stuff */
public UpdateRunnable(Activity activity, Handler mHandler){
this.activity = activity;
this.mHandler = mHandler;
/* Other stuff */
}
#Override
public void run() {
// It get from web which Dialog to call
update = update();
// It manage the UI work
mHandler.post(new Runnable() {
public void run() {
if(update){
show_dialog_you_are_not_updated();
} else {
show_dialog_you_are_updated();
}
}
});
}
/* The methods update, show_dialog_you_are_not_updated, show_dialog_you_are_updated */
}
I am learning how to use Looper and Handler class in android development
http://developer.android.com/reference/android/os/Looper.html
The example given in the android development is not clear to understand what is the usage and the how to use it.I dont know how to add Handler inside the Looper and how I can call the Looper to loop.
If it is available, can anyone give me a simple example to use it.
public class LooperTest extends Activity{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
private class LooperTesting extends Thread
{
public Handler handler;
public void run()
{
Looper.prepare();
handler = new Handler()
{
public void handlerMessage(Message msg)
{
// do something
}
};
Looper.loop();
}
}
}
Hope this Links are helps to u
Link1
Link2
Link3
In your example you have only defined a Thread with a Looper. You need to start the Thread with the associated Looper before you can post any messages to it. I've added some code to your example to illustrate what has to be done:
public class LooperTest extends Activity{
LooperTesting mBgThread;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBgThread = new mBgThread();
// Start the thread. When started, it will wait for incoming messages.
// Use the post* or send* methods of your handler-reference.
mBgThread.start();
}
public void onDestroy() {
// Don't forget to quit the Looper, so that the
// thread can finish.
mBgThread.handler.getLooper().quit();
}
private class LooperTesting extends Thread
{
public Handler handler;
public void run()
{
Looper.prepare();
handler = new Handler()
{
public void handlerMessage(Message msg)
{
// do something
}
};
Looper.loop();
}
}
}