Below is the code for simple get request and res variable is not available inside Ui thread. How this can be achieved in android?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread(new Runnable(){
#Override
public void run(){
try {
String res = Utils.GetRequest("http://www.google.com");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, res, Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
Okay, I found out that I haven't declared the res variable as final.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread(new Runnable(){
#Override
public void run(){
try {
final String res = Utils.GetRequest("http://www.google.com");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, res, Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
You have to create a handler on the Main thread in the OnCreate()
Handler mHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message inputMessage) {
// handle the passed value here
// for ex. update the UI by getting the data from the inputMessage
}
}
inside your Thread .. call the
Message myMessage = mHandler.obtainMessage();
myMessage.obj = "the value to update the ui";
mHandler.sendMessage(myMessage);
Related
I have tried updating my user interface using the text view what i have done is a run a while loop indefinitely and left the thread for sleep for one second..
int i;
while(true)
{
Thread.Sleep(1000);
textView.setText(updateTime);
}
Use runOnUiThread and surround with try catch for Thread.sleep(1000)
int i;
while(true)
{
try {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
textView.setText(updateTime);
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Try this one arnab...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = (TextView) findViewById(R.id.displayid);
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
bundle = msg.getData();
textView.setText(bundle.getString("mKey"));
}
};
}
public void press(View v) {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (this) {
try {
wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bundle = new Bundle();
message = handler.obtainMessage();
simpleDateFormat = new SimpleDateFormat("hh:mm:ss YYYY/mm/dd", Locale.US);
date = simpleDateFormat.format(new Date());
bundle.putString("mKey", date);
message.setData(bundle);
handler.sendMessage(message);
}
}
}
}).start();
}
Try runOnUiThread:
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(updateTime);
}
});
tv value set to value 1 then after 5000 it does not set its value , showdown the app
tv = (TextView) findViewById(R.id.textView1);
Thread time = new Thread(){
public void run(){
try{
tv.setText("Value 1");
sleep(5000);
tv.setText("Value 2");
}
catch ( InterruptedException e){
e.printStackTrace();
}finally{
tv.setText("Value 3");
}
}
};
time.start();
You should call Activity.runOnUiThread() to update the UI from other threads.
Thread t = new Thread() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
tv.setText("Value 1");
}
});
}
};
OR
Use a Handler:
Thread t =new Thread(){
public void run() {
handler.post(new Runnable() {
public void run() {
tv.setText("Value 1");
}
});
}
}};
You have to run the code that deals with UI on the main thread... it's called UIThread... you can do any thing on another threads except handling UI
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
tv.setText....
}
});
You have to run the TextView update method inside the runOnUiThread() method. Your code should look something like this:
Thread time = new Thread() {
public void run() {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
tv.setText("Value 1");
}
});
sleep(5000);
runOnUiThread(new Runnable() {
#Override
public void run() {
tv.setText("Value 2");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
tv.setText("Value 3");
}
}
};
time.start();
I set a textview, which I use for timer-function.
When the timer reachs my wanted time it should start a new activity, that set my Layout to another one.
textfield=(TextView)findViewById(R.id.TVTimer);
handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
while (Running){
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
handler.post(new Runnable() {
#Override
public void run(){
number+=1;
textfield.setText(String.valueOf(number));
if (number>5) {
Intent intent = new Intent(getApplicationContext(), Uebung2.class);
startActivity(intent);
}
}
} );
}
}
};
new Thread(runnable).start();
That is the called class:
public class Uebung2 extends Oberklasse {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//Liegestützen1(2);
setContentView(R.layout.new);
}
}
Now I am having the problem after the timer reached the time, which I want, my app is settin g the layout again and again for every second.
What is the solution to set the layout for once?
beacuse you have place this
handler.post(new Runnable() {
#Override
public void run(){
number+=1;
textfield.setText(String.valueOf(number));
if (number>5) {
Intent intent = new Intent(getApplicationContext(), Uebung2.class);
startActivity(intent);
}
}
} );
inside your while loop.
also check your "number" value.
try your while loop as
int i=1000;
while (i<5000){
try {
Thread.sleep(i);
i+=1000;
}
catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
}
and after this execute your runnable.
use this
textfield=(TextView)findViewById(R.id.TVTimer);
boolean loop = true;
handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
while (loop){
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
handler.post(new Runnable() {
#Override
public void run(){
number+=1;
textfield.setText(String.valueOf(number));
if (number>5) {
loop = false; // this will end loop
Intent intent = new Intent(getApplicationContext(), Uebung2.class);
startActivity(intent);
}
}
} );
}
}
};
new Thread(runnable).start();
timer.setText("setTextHere") does not work inside the thread.
Thread thread1 = new Thread(){
TextView timer;
int t;
public void run(){
timer=(TextView) findViewById(R.id.timer);
try{
timer.setText("setTextHere");
sleep(5000);
}
catch(Exception e){
e.printStackTrace();
}
finally{
Intent new1 = new Intent("com.example.app1.MENU");
startActivity(new1);
}
}
};
thread1.start();
_t = new Timer();
_t.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
_count++;
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
_tv.setText( "" + _count );
}
});
}
}, 1000, 1000 );
You cannot touch UI from background thread. Try to use AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html
On your onCreate() add:
h = new Handler();
add this somewhere:
class SetText implements Runnable {
public void run() {
// do UI task
timer.setText("setTextHere");
}
}
on someFunction() modify like this:
...
try
{
h.post( new SetText() );
sleep(5000);
}
...
final TextView timer = (TextView) findViewById(R.id.timer);
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
timer.post(new Runnable() {
public void run() {
timer.setText("setTextHere");
}
});
} catch (Exception e) {
e.printStackTrace();
} finally {
Intent new1 = new Intent("com.example.app1.MENU");
startActivity(new1);
}
}
}).start();
you could use this and initialize the setText before initializing the Thread
Thread thread1 = new Thread(){
int t;
public void run(){
try{
sleep(5000);
}
catch(Exception e){
e.printStackTrace();
}
finally{
Intent new1 = new Intent("com.example.app1.MENU");
startActivity(new1);
}
}
};
TextView timer;
timer=(TextView) findViewById(R.id.timer);
timer.setText("setTextHere");
thread1.start();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ThraedDemo objDemo = new ThraedDemo();
Thread objThread = new Thread() {
#Override
public void run() {
objDemo.firstMethod();
}
};
objThread.start();
}
class ThraedDemo {
private void firstMethod() {
Thread objThread = new Thread() {
#Override
public void run() {
try {
((ImageView)findViewById(R.id.ImageViewnumber)).setImageResource(nums[n]);
Thread.sleep(10000);
Log.v("Thread","1111111111111111sleep");
} catch (InterruptedException ex) {
System.out.println("interuped exception" + ex.getMessage());
}
secondMethod();
}
private void secondMethod() {
Thread objThread = new Thread() {
#Override
public void run() {
try {
((ImageView)findViewById(R.id.ImageViewResult)).setImageResource(nums[n+1]);
n++;
Thread.sleep(10000);
Log.v("Thread","22222222222 sleep");
} catch (InterruptedException ex) {
System.out.println("interuped exception" + ex.getMessage());
}
firstMethod();
}
};
objThread.start();
}
};
objThread.start();
}
}
I use the above code but it is not running.it got CalledFromWrongThreadException what is the problem inb the above code.Please give me some suggestions.Thanks in advance
I think you can't do view modifications from another thread than the UI thread, so either create handlers in the oncreate and post your thread to it, or use AsyncTask, or runOnUIThread method to send portions of code directly to the UI thread.
I edited your 2nd function code, I see your code is loop forever cause the firstMethod call secondMethod and the secondMethod call the new firstMethod to start and then loop forever. I removed it and moved the code update ImageView into the UI Thread, could you try this:
class ThraedDemo {
private void firstMethod() {
Thread objThread = new Thread() {
#Override
public void run() {
try {
runOnUiThread(new Runnable() {
public void run(){
((ImageView)findViewById(R.id.ImageViewnumber)).setImageResource(nums[n]);
}
});
Thread.sleep(10000);
Log.v("Thread","1111111111111111sleep");
} catch (InterruptedException ex) {
System.out.println("interuped exception" + ex.getMessage());
}
secondMethod();
}
};
objThread.start();
}
private void secondMethod() {
Thread objThread2 = new Thread() {
#Override
public void run() {
try {
runOnUiThread(new Runnable() {
public void run(){
((ImageView)findViewById(R.id.ImageViewnumber)).setImageResource(nums[n+1]);
}
});
n++;
Thread.sleep(10000);
Log.v("Thread","22222222222 sleep");
} catch (InterruptedException ex) {
System.out.println("interuped exception" + ex.getMessage());
}
}
};
objThread2.start();
}
}