I am wondering about the post method use into the Thread class.
My program is about to find fixed salary from the basic salary.Basically in this program ,I have one editText where user have to enter the basic salary and when the click on the button called 'show' there is one counter which display on the screen 1,2,3,...10 in textview.Then after the fixed salary will displayed on other editText.So,this about my program
Now,In code I have make one class called Mythread for the counter purpose.In which I have put the loop which count 1,2,...10.But my problem is that the i want to refresh the values of the textView so i want to use post method but how to use in my code that i don't know.
Kindly guide me
package com.example.bs_to_fs_thread;
import android.widget.TextView;
public class MyThread extends Thread{
TextView _tv;
String fs;
public MyThread(TextView tv,String sfs){
_tv=tv;
fs=sfs;
}
public void run()
{
int i=0;
while(i<10)
{
_tv.post(new Runnable()
{
public void run()
{
_tv.setText(i);
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
MainActivity.printFS(fs);
}
}
`
In this code ,may be I write the _tv.post(Runnable{ });
on wrong place pls give me the view of this post method and how should and where should i write this post method? and why?
Try something like this(I have not tested it dont have editor now):
public MyThread(TextView tv,String sfs,Activity a){
this._tv=tv;
this.fs=sfs;
this.a= a;//this is required to use method runOnUiThread as background thread cannot modify Ui thread
}
Then in the place where you want to modify your UI like change text do something like this:
a.runOnUiThread(new Runnable() {
public void run()
{
Toast.makeText(a, "show some toast", Toast.LENGTH_SHORT).show();
_tv.setText("mytext");
}
});
Try this:
public void run() {
int i = 0;
while(i < 10) {
// We can't use 'i' directly inside the runnable declaration, because all
// external variables must be declared as final
final int number = i;
// Posting this runnable to the UI thread
_tv.post(new Runnable() {
public void run() {
_tv.setText(number);
}
}
// Sleeping current thread (NOT UI thread) for 1 second
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Increment 'i'
i++;
}
MainActivity.printFS(fs);
}
Related
I have multiline TextView on my Fragment. This TextView must to show data from Thread.
private void method1(){
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
int index = 0;
while (index < 100){
updateLog(Integer.toString(index));
index ++;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
}
private void updateLog(String log){
currentActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
syncLogTextView.append(log+" \n");
}
});
}
It's works, but if I want to switch to another fragment, I will lose all data in TextView. After return I will have empty TextView. I need to save and restore data in TextView and synchronize with my thread. How I can implement correctly it?
I would separate log - thread (data) part from view
You can create a storage (private String mystore) and update it with thread
and take data from property (storage) as soon as you want to show it
I am making a project in which i am using the progressdialog and i want to show this progress dialog on creation of activity and i am able to that. In the on create method i want the image to be invisible and i want image to be visible after completion of progress dialog but it is throwing exception in the line imagevisible();
The logcat is:
04-12 12:48:35.309: E/AndroidRuntime(4994): at com.example.project1.ShowPassword$waiter.run(ShowPassword.java:59)
Code
ImageView iv;
ProgressDialog p;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.showpass);
iv=(ImageView)findViewById(R.id.imageView1);
iv.setVisibility(View.INVISIBLE);
p= new ProgressDialog(this);
p.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
p.setTitle("Getting Password: ");
p.setMessage("Loading:");
p.setMax(100);
p.show();
Thread t=new Thread(new waiter());
t.start();
public class waiter extends Thread{
public void run(){
for(int i=0; i<5; i++){
p.incrementProgressBy(20);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}p.dismiss();
imagevisible();
}
}
public void imagevisible(){
iv.setVisibility(View.VISIBLE);
}
You can't change UI from non UI thread. You can use runOnUiThread method of Activity:
public class waiter extends Thread{
public void run(){
//...
runOnUiThread(new Runnable() {
#Override
public void run() {
imagevisible();
}
});
}
}
What you want is an AsyncTask. Implement doInBackground() (runs in the background) and onPostExecute() (runs on the UI thread).
https://developer.android.com/reference/android/os/AsyncTask.html
I want to add and clear window flag inside a thread but not working. Basically i want my thread to keep the screen on for two seconds and then clear the screen on flag.
Here's my code:
public class WriteCommThread extends Thread {
private long time=2000;
public WriteCommThread(float count) {
time = (long) count;
}
public void run() {
while(connectionUnAbort==true){
// Lock screen
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
slleep();
//Unlock screen
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
connectionUnAbort=false;
}
}
public void slleep(){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I solved it after doing research, i am posting the referred link.
Answer Link
Here's my solution to my problem and it worked perfectly. I added these runnable classes in my background thread (run method). And after sleeping i could clear the flag to keep the screen on.
runOnUiThread(new Runnable() {
public void run() {
//stuff that updates ui
MainActivity.this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
runOnUiThread(new Runnable() {
public void run() {
//stuff that updates ui
MainActivity.this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
PROBLEM
I have nearly 20 TextView and I need to have do something to make their background color change dynamically.
For example: all TextView have same default background color then after 5 sec first one's will turn red where others still same then after 5 more sec passed first TextView's background color will turn to default and second TextView's background color will be turn to red and it will go on like this.
I tried to put them in for loop in thread and handler but they changed all together. What should I do ?
I have tried this code
Thread color=new Thread() {
public void run() {
for(int i=2131230724;i<=2131230742;i++){
TextView currentText = (TextView) findViewById(i);
currentText.setBackgroundColor(Color.RED);
try {
sleep(2000);
currentText.setBackgroundColor(Color.TRANSPARENT);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
then I used
mHandler.post(color);
SOLUTION
I found a solution for my problem and sharing if someone else needed too.
Runnable myhandler=new Runnable() {
int id=2131230724;//First textView id
#Override
public void run() {
// TODO Auto-generated method stub
if(id==2131230724){
TextView currentText=(TextView)findViewById(R.id.egzersiz01_kelime1);
currentText.setBackgroundColor(Color.RED);
id++;
}
else if(id==2131230725){
TextView currentText=(TextView)findViewById(R.id.egzersiz01_kelime2);
currentText.setBackgroundColor(Color.RED);
TextView PreText=(TextView)findViewById(R.id.egzersiz01_kelime1);
PreText.setBackgroundColor(Color.TRANSPARENT);
id++;
}//And all other id's to else if as same as mine.
mHandler.postDelayed(myhandler, delay);
and in onCreate()
myhandler.run();
I have tried to use for loop to make it easy but it crashed and I had to write them all.
Thanks for helping...
You can put the params to AsynTask like this, and then
new changeColor().execute(max);
private class changeColor extends AsyncTask<Integer,Integer,Void>{
int max,cur;
#Override
protected void onPreExecute() {
max=cur=0;
super.onPreExecute();
}
#Override
protected Void doInBackground(Integer... number) {
int max=number[0];
int cur=1;
if(max>0)
while(true ){/*or other condition else*/
try {
Thread.sleep(5000);//Sleep 5000s before make change
} catch (InterruptedException e) {
Log.i("TAG","InterruptedException");
}
publishProgress(cur);
if(cur==max)
cur=1;
else
cur++;
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
changeColorTextView(values[0]);
super.onProgressUpdate(values);
}
private void changeColorTextView(int textViewId){
switch(textViewId){
case textId1:{
//do some thing here like:
//textView2.setBackGroundColor(R.color.RED);
//textView1.setBackGroundColor(default);
break;
}
//....
}
}
}
I just want to continously update text in an android app. However my App crashes every time.
This is my code:
package org.pgvw.main;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class InertialView extends Activity {
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
tv.setText("Time: ");
new Thread(new Runnable() {
public void run() {
while(true) {
try {
Thread.currentThread().sleep(100);
tv.setText("Time: " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
setContentView(tv);
}
}
Can anyone spot the mistake?
Greetings and thx!
Consider that you do not need to launch any additional threads to update the UI every x milliseconds. The additional overhead of an added thread is justified IF you have a time intensive task. In the following example the timer is launched on a button click. Note that this code does not create a new thread.
private Handler myHandler= new Handler(){
#Override
public void handleMessage(Message msg){
switch(msg.what){
case 0:
if (!isDoneThinking){
editTextConfusedText.setText("Still Thinking "+new Integer(thinkSeconds).toString());
thinkSeconds++;
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0),1000); // <== Loop on delayed messages every second
}
else {
thinkSeconds= 0; // reset timer
}
break;
default:
super.handleMessage(msg);
break;
}
}
};
We launch the timer in onClick. We simply send an empty message with a what value of "0".
buttonConfuseText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
isDoneThinking= false;
myHandler.sendEmptyMessage(0); <== starts timer with what value of "0"
}
};
The timer is unconstrained and will continue to count until the flag isDoneThinking is set to true.
You cannot update GUI from another thread. You can use runOnUiThread or handler to update the GUI.
for example:
new Thread(new Runnable() {
public void run() {
while(true) {
try {
Thread.currentThread().sleep(100);
runOnUiThread(new Runnable() {
public void run() {
tv.setText("Time: " + System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
BTW - The use of Thread.currentThread().sleep(100); can be shorted to Thread.sleep(100) since it's a static method. see Jon Skeet's answer regarding that
Or use AsyncTask. It was designed to do background tasks and properly update the UI. Your design will be more scalable this way.