Why Thread goed to sleep first and sets TextView later in Activity? - android

Here is the code e.g. of result set in android first activity with UI having 3 EditText and 3 Buttons or TextView. I need to set values in 2nd TextView to display total marks which is calculated from first 3 EditText and sleep for 10sec in main method without using thread but I am getting op ie after going to sleep 10sec and immediately showing total TextView and navigated to next activity ie mentioned in code so how to wait for 10sec after setting total
EditText etMarkOne,etMarkTwo,etMarkThree;
TextView tvTMarks,tvTotal,tvGrade;
int m1,m2,m3,Tmarks;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inilizeViewControls();
eventHandlingonViewControls();
}
private void eventHandlingonViewControls(){
tvTotal.setOnClickListener(this);
}
private void inilizeViewControls() {
etMarkOne = (EditText) findViewById(R.id.etMarkOne);
etMarkTwo = (EditText) findViewById(R.id.etMarkTwo);
etMarkThree = (EditText) findViewById(R.id.etMarkThree);
tvGrade = (TextView) findViewById(R.id.tvGrade);
tvTMarks = (TextView) findViewById(R.id.tvTMarks);
tvTotal= (TextView) findViewById(R.id.tvTotal);
}
#Override
public void onClick(View v) {
m1 = Integer.parseInt(etMarkOne.getText().toString());
m2 = Integer.parseInt(etMarkTwo.getText().toString());
m3 = Integer.parseInt(etMarkThree.getText().toString());
Tmarks = m1 + m2 + m3;
tvTMarks.setText(""+Tmarks);
Thread.sleep(2000);
Intent i = new Intent(MainActivity.this,ResultActivity.class);
i.putExtra("Tmarks",Tmarks);
i.putExtra(" m1", m1);
i.putExtra(" m2", m2);
i.putExtra(" m3",m3);
startActivityForResult(i,1);
}
}

You can use Handler for your task (10000 in postDelayed() means 10sec = 10000ms):
Handler handler = new Handler();
// do work before delay here
...
handler.postDelayed(new Runnable() {
public void run() {
// do work after delay here
...
}
}, 10000);

Related

How to make live dialog?

I have to build a custom dialog that update the view when the content view is changed.
In the example below I have two TextView, one in the main activity and one in the dialog layout and counter from 1 to 10 should showed on both (main activity layout and dialog layout), but only the TextView in the main activity is update.
The code:
TextView tvCounter_Dialog, tvCounter_OutsideDialog;
int counter = 0;
Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_custom_dialog);
handler = new Handler();
View dialogView = getLayoutInflater().inflate(R.layout.dialog_live_layout, null);
tvCounter_Dialog = (TextView) dialogView.findViewById(R.id.tvCounter);
tvCounter_OutsideDialog = (TextView) findViewById(R.id.tvCounter_outsideDialog);
Dialog counterDialog = new Dialog(this);
counterDialog.setContentView(R.layout.dialog_live_layout);
counterDialog.show();
final Runnable updatedr = new Runnable() {
#Override
public void run() {
counter = (counter + 1) % 10;
tvCounter_Dialog.setText(String.valueOf(counter));
tvCounter_OutsideDialog.setText(String.valueOf(counter));
handler.postDelayed(this, 500);
}
};
updatedr.run();
}
So the question is - how can I update the textview in the dialog?
EDIT: here is an capture (to be more clear)
the mistake is on this line
counterDialog.setContentView(R.layout.dialog_live_layout);
it should be
counterDialog.setContentView(dialogView);
in your version the custom view of your Dialog and the one you inflated are different

resolve 'called from wrong thread' exception

The purpose of my app is: User enters a number and clicks a button. The button uses the input to calculate the Fibonacci sequence with a timer - with each number in the sequence displaying each second to a textView. But when I try to run the timer I get the CalledFromWrongThreadException. I've posted my code below. As you can tell by my log statements I believe I know which line is causing the problem. I think it's because I'm calling a method which is outside my onclicklistener but when I move that other method around I just cause more problems.
I've read a couple other posts and I'm not really sure what the proper way is to print to a text area using my method. Does anyone know how I can make this work?
public class MainActivity extends Activity {
// primary widgets
private EditText editText;
private TextView textView;
private Button button1;
static int seconds = 0;
static Timer timer;
static ArrayList<Integer> fibList = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText1);
textView = (TextView) findViewById(R.id.textView2);
button1 = (Button) findViewById(R.id.button1);
final int delay = 1000;
final int period = 1000;
timer = new Timer();
//Attempt to clear TextView
textView.setText("");
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Clear Textview
String array = " ";
fibList.clear();
textView.setText(array);
//Log.i("ARRAY", "ATTEMPT to CLEAR"+fibList);
String input = editText.getText().toString();
int number = Integer.parseInt(input);
int tmp = 0;
// confirm input
if (number < 20) {
Toast.makeText(getApplicationContext(),
"You entered: " + number, Toast.LENGTH_LONG).show();
for (int i = 0; i <= number; i++) {
fibList.add(fib(i));
// sum even numbers
if (fib(i) % 2 == 0) {
tmp += fib(i);
}
}
} else {
Toast.makeText(getApplicationContext(),
"Number is too Large: " + number, Toast.LENGTH_LONG)
.show();
}
//I believe error occurs in this method
Log.i("TEST", "START TIMER");
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.i("TEST", "RUN TIMER");
int nextIndex = setInterval();
Log.i("TEST", "SET INTERVAL");
if (nextIndex < fibList.size()) {
Log.i("TEST", "TRY TO PRINT");
//It looks like error occurs here when I try to print to textView
textView.setText(fibList.get(nextIndex)+ " ");
Log.i("TEST", "NEXT INDEX"+fibList.get(nextIndex));
Log.i("TEST", "DID PRINT");
}
}
}, delay, period);
Log.i("TEST", "END TIMER");
}
});
}
// run fibonacci sequence
public static int fib(int n) {
if (n < 2) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
//counts up for every element through the array
public static final int setInterval() {
if (seconds >= fibList.size())
timer.cancel();
return seconds++;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
You can use
runOnUiThread(new Runnable(){
public void run(){
textView.setText("aaa");
}
});
Have your timer post a message to a Handler. The handler will, by default, run on the main thread. IT can then change the UI as needed, so just put the body of your timer into that handler.
I just had this problem and came on to StackOverflow to check out a solution. Didn't find anything proper but a little more experimenting with lot many Logs and debugging got me my solution.
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText("Your String");
}
});
In my code, the problem was due to me accessing Two TextViews in seperate threads one after another using TextView.post(new Runnable...). I guess this was due to it not being able to access UI Thread (as it was busy with previous thread changes). Setting both TextViews together in UI Thread solved the problem. So posting here for anyone else who might be perplexed by similar problem. Hope it helps.

How to reset variable in runnable in Android

I have a handler and a runnable, Handler has a loop that runs from 0 to 5. when i start the runnable in handler it runs and increment value to 0 to 5. But if i double click or click more than 1 time than it takes the value of temp above 5. How can i reset (0) the value of temp on every click of handler.
final Handler deneme = new Handler();
final Runnable post_score = new Runnable(){
public void run(){
Log.i("TAG", Integer.toString(temp));
temp++;
}
};
Button tv = (Button )findViewById(R.id.button1);
tv.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
temp = 0;
for(int i=0; i < 5;i++){
deneme.postDelayed(post_score, i *250);
}
}
});
the best way is to use removecallback

Dynamic background based on a timer (linear layout), how to?

Hi I'm kind of beginner to android OS programming, and I got stuck with a problem, I cant figure out how to do a dynamic background, based on timers (say each 10 seconds a background changes to a different one) I have some code but it comes up with error, here's a sample:
private static final long GET_DATA_INTERVAL = 10000;
int images[] = {R.drawable.smothie1,R.drawable.omletherb1};
int index = 0;
ImageView img;
Handler hand = new Handler();
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
LinearLayout layout= (LinearLayout)findViewById(R.id.LinearView1);
hand.postDelayed(run, GET_DATA_INTERVAL);
}
Runnable run = new Runnable() {
public void run() {
layout.setBackgroundResource(LinearView1).getDrawable(images[index++]);
if (index == images.length)
index = 0;
hand.postDelayed(run, GET_DATA_INTERVAL);
Any help would be greatly apprieciated :D thanks
EDIT: The errors I get are on this line:
layout.setBackgroundResource(LinearView1).getDrawable(images[index++]);
It says that:
-layout cannot be resolved
-the method getDrawable(int) is undefined for the type Object
This error:
layout.setBackgroundResource(LinearView1).getDrawable(images[index++]);
It says that:
-layout cannot be resolved
-the method getDrawable(int) is undefined for the type Object
Please help :)
I have finally worked it out, after removing a few errors I have came up with this (and its working) :
public class CookBookActivity extends Activity {
/** Called when the activity is first created. */
private static final long GET_DATA_INTERVAL = 1000;
int images[] = {R.drawable.omletherb1,R.drawable.smothie1};
int index = 0;
LinearLayout img;
Handler hand = new Handler();
private LinearLayout layout;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
layout = (LinearLayout)findViewById(R.layout.main);
hand.postDelayed(run, GET_DATA_INTERVAL);
Typeface tf2 = Typeface.createFromAsset(getAssets(),
"fonts/BPreplay.otf");
TextView tv2 = (TextView) findViewById(R.id.textView2);
tv2.setTypeface(tf2);
Typeface tf = Typeface.createFromAsset(getAssets(),
"fonts/BPreplay.otf");
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setTypeface(tf);
Button mainNext = (Button) findViewById(R.id.nextScreen1);
mainNext.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent i = new Intent();
i.setClassName("com.unKnown.cookbook", "com.unKnown.cookbook.screen1");
startActivity(i);
}
});
}
Runnable run = new Runnable() {
public void run() {
layout.setBackgroundDrawable(getDrawable(index++));
if (index == images.length)
index = 0;
hand.postDelayed(run, GET_DATA_INTERVAL);
}
};
protected Drawable getDrawable(int i) {
// TODO Auto-generated method stub
return getResources().getDrawable(images[i%2]);
}
}

How do I delay text from being displayed in textView - using input from the user

I am trying to make a simple application where every so many seconds the text being displayed is changed to another, the input is given by the user before the onClick and set to different strings. I can't find a way to have the different strings displayed at different times - and is it even possible to use one single textView to display different text at different times, never at the same time....
Any help is appreciated. Thanks.
Andrew
This is my code so far...
public class ThunderActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//when the game button is pressed
final Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Enter names
//player one
final EditText player1 = (EditText) findViewById(R.id.editText1);
final String player = player1.getText().toString().trim();
//player 2
final EditText player2 = (EditText) findViewById(R.id.editText2);
final String player11 = player2.getText().toString().trim();
//player 3
final EditText player3 = (EditText) findViewById(R.id.editText3);
final String player111 = player3.getText().toString().trim();
//switches to second screen - the play xml file
setContentView(R.layout.main2);
//starts the song
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.drawable.thunderstruck);
mp.start();
//shuffle names and display them
//displays name - testing purposes
v = (TextView) findViewById(R.id.textView1);
String text = player;
((TextView) v).setText(text);
//v = (TextView) findViewById(R.id.textView2);
//String text2 = player11;
//((TextView) v).setText(text2);
}
});
}
}
An easier way to do the same thing is using the Handler.postDelayed method.
public class Act extends Activity{
private Handler handler = new Handler();
private TextView view;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Initialize view
handler.postDelayed(new ViewUpdater("str1", view), 10000);
handler.postDelayed(new ViewUpdater("str2", view), 20000);
handler.postDelayed(new ViewUpdater("str2", view), 30000);
}
private class ViewUpdater implements Runnable{
private String mString;
private TextView mView;
public ViewUpdater(String string, TextView view){
mString = string;
mView = view;
}
#Override
public void run() {
mView.setText(mString);
}
}
}
Something like that: You get the basic idea!
ok here is your hint:
Say your TextView is called yourTextView
String[] texts = new String[]{"String1","String2","String3"}; //etc
Runnable myRun = new Runnable(){
public void run(){
for(int i=0;i<texts.length;i++){
synchronized(this){
wait(30000); //wait 30 seconds before changing text
}
//to change the textView you must run code on UI Thread so:
runOnUiThread(new Runnable(){
public void run(){
yourTextView.setText(texts[i]);
}
});
}
}
};
Thread T = new Thread(myRun);
T.start();
A more correct answer would be to use a ViewFlipper. You can add all your TextViews to it and call startFlipping(). You can set the flip interval by calling setFlipInterval(int milliseconds).

Categories

Resources