There is an int value that continuously get updated inside a thread and I want to show the value in a textview but i m unable to use findviewbyid inside of thread ?
How to refer to that textview from inside that thread and update it accordingly?
Here is my code:
package com.example.raj.testview;
import android.widget.TextView;
public class TextChange implements Runnable
{
public void run()
{
TextView tv=(TextView)findViewById(R.id.tv);
for(int i=0;i<10000;i++)
{
tv.setText(String.valueOf(i));
}
}
}
You cannot change UI elements from a non-UI thread. Try using runOnUiThread.
runOnUiThread(new Runnable(){
#Override
public void run(){
// change UI elements here
}
});
Related
I am a newer to Android development. now I want to show current system time in a thread via textview control. I get some example and can start the thread to draw text in textview control.
but when I trid to get system current time via below link:Display the current time and date in an Android application, I got errors,The error saying:getDateTimeInstance() is undefined for the type DateFormat.
Why this answer didn't work for me ? thx.
below is the code for your reference:
public class MainActivity extends Activity {
private TextView timeView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(){
public void run(){
System.out.println("Thread is running!!");
timeView = (TextView)findViewById(R.id.textView1);
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
timeView.setText("I am Fired via Non-UI thread:"+s);
}
}.start();
}
Updatin ui in a thread not possible
timeView.setText("I am Fired via Non-UI thread:"+s);
Use runOnUiThread. Inside thread's run method
runOnUiThread(new Runnable() {
#Override
public void run() {
timeView.setText("I am Fired via Non-UI thread:"+s);
}
});
Also initialize textview in outside the thread
timeView = (TextView)findViewById(R.id.textView1)
Also check this
http://developer.android.com/reference/java/text/DateFormat.html
Check your import statement.
import java.text.DateFormat // import this
instead of
import android.text.format.DateFormat;
I have SurfaceView and Run() method , Its like a loop , how can i edit textView text in this Run method ?
I wrote :
textView1.setText("my text");
It didn't work ? any Ideas ?
the code summary is :
public class GFXSurface extends Activity {
MySurface ourSurfaceView;
TextView textView1;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(ourSurfaceView);
}
public class MySurface extends SurfaceView implements Runnable{
#Override
public void run() {
//here i want to edit textView1
}
}
}
You cannot alter Views that were initialized on the main thread from another thread. You should look into using a Handler to post on the UI thread. It wouldn't be wise to update a TextView inside that run method either, but I'm not sure what you're trying to accomplish exactly.
You can try setting text to your TextView using the runOnUiThread() method call, for example the following:
runOnUiThread(new Runnable(){
public void run() {
//here set the textview content
}
});
I have this project:
Im trying to undestand where is the problem and how can be solved, but a this simply point I really dont know where is the problem.
I have a button and a TextView.
When the button is clicked this procedure is called:
android:onClick="pulsaboton"
And the TextView show me the output.
This is Main_Activity.java
package com.example.pruebasonidos;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
public String cadena1="", cadena2="";
public TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textview01);
}
public class generamusica extends AsyncTask<String, Integer, Integer>
{
#Override
protected void onPreExecute(){
tv.setText(tv.getText().toString()+"Pre Execute");
}
#Override
protected Integer doInBackground(String...strings) {
String cadena=strings[0];
tv.setText(tv.getText().toString()+cadena);
return null;
}
#Override
protected void onPostExecute(Integer bytes){
tv.setText(tv.getText().toString()+"Post Execute");
}
}
public void pulsaboton(View v) {
cadena1="123"; cadena2="111";
tv.setText("");
new generamusica().execute(cadena1);
new generamusica().execute(cadena2);
}
#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;
}
}
When pulsaboton is clicked, textview1 display this:
PreExecutePreExecute123111PostExecutePostExecute
I want this output:
PreExecute123PostExecutePreExecute111PostExecute
What is the error????
WARNING: INTERFACE MODIFICATION EXECUTED OUTSIDE OF UI THREAD!
protected Integer doInBackground(String...strings) {
...
tv.setText(tv.getText().toString()+cadena);
...
}
Why do you think AsyncTask exposes onPreExecute and onPostExecute? Couldn't you just do all of your interface work in doInBackground, before and after your async code?
In Android, the UI needs to be accessed from the main thread, the foreground thread; which doInBackground is not run in.
If you need to post updates to your UI during the execution of an AsyncTask, use the publishProgress mechanism.
Edit: "properly" accesing the interface is a lot more complex that just using onPreExecute and onPostExecute. See this blog post. Maybe you should try the Loader API, it's less troublesome.
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution..
http://developer.android.com/reference/android/os/AsyncTask.html
You are updating ui on the background thread which is not possible. You need to update ui on the ui thread
In doInBackground()
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
String cadena=strings[0];
tv.setText(tv.getText().toString()+cadena); ;
}
});
For your required output Call these two lines in onPostExecute,
cadena2="111";
new generamusica().execute(cadena2);
And dont try to update the UI in background thread.
See This for more info
I have a question regarding an Android application. I want to, later on, create a game and i am currently trying out classes and functions that I need to understand.
At the moment im trying to get a grip of how to use threads in a good way, but my application is "force closing" when i touch the button.
For this test application, all have on the screen is one TextView and one button.
The button is calling threadStart() when pressed. (onClick in xml)
And what i want it to do is to create a thread which increases the variable value by 1 and then report to the UI thread which then update the textview with the new value.
Can someone see what i am doing wrong with this small pice of code?
package com.weldeborn.tc;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
public class ThreadCounter extends Activity {
TextView txtCounter1;
int value=0;
final Handler mHandler = new Handler();
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResult();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtCounter1 = (TextView) findViewById(R.id.counter1);
}
protected void threadStart() {
Thread t = new Thread() {
public void run() {
doSomething();
mHandler.post(mUpdateResults);
}
};
t.start();
}
private void doSomething() {
value = value+1;
}
private void updateResult() {
txtCounter1.setText(value);
}
}
My code is based on an example from Android Developer: The Common Tasks and how to do them section under the "Handling Expensive Operations in the UI Thread" heading.
I am thankful for any help.
setText doesn't work correctly when you pass an integer, directly. Try converting it to String before:
txtCounter1.setText(String.valueOf(value));
Also, check this answer about the usage of threads that need to update the UI.
if threadStart is your onClick the signature needs to be
public void threadStart(View v)
If you have a handle to a Spinner object in an Android Activity, can you programmatically pop open the spinner options - thereby forcing the user to choose an option even though they did not click on the Spinner themselves?
To open the Spinner you just need to call it's performClick() method.
Keep in mind that you may only call this method from the UI thread. If you need to open the Spinner from a separate thread you should create a Handler in the UI thread and then, from your second thread, send a runnable object that calls performClick() to the Handler.
package com.example.SpinnerDemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.os.Handler;
public class SpinnerDemo extends Activity {
private Handler h;
private Spinner s;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
h = new Handler();
s = (Spinner) findViewById(R.id.spinner);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
R.array.planets, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
s.setAdapter(adapter);
// Open the Spinner...
s.performClick();
// Spawn a thread that triggers the Spinner to open after 5 seconds...
new Thread(new Runnable() {
public void run() {
// DO NOT ATTEMPT TO DIRECTLY UPDATE THE UI HERE, IT WON'T WORK!
// YOU MUST POST THE WORK TO THE UI THREAD'S HANDLER
h.postDelayed(new Runnable() {
public void run() {
// Open the Spinner...
s.performClick();
}
}, 5000);
}
}).start();
}
}
The resources used by this example can be found here.
To show the Spinner items you just need to call it's performClick() method.
Spinner spDeviceType = (Spinner) findViewById(R.id.spDeviceType);
spDeviceType.performClick();
You don't need to use 2 runnables as shown in the previous example.
This will be enough :
h.postDelayed(new Runnable() {
public void run() {
s.performClick();
}
}, 5000);
Simply use this
yourspinner.performClick();
#Override
protected void onResume() {
super.onResume();
_spinner_operations.performClick();
}
you need the call in onResume, in onCreate this not work.
You can call performClick() after the UI thread is done with its current operation(s). If you don't use post {}, you may not see the Spinner open.
findViewById<Spinner>(R.id.spinner).post {
performClick()
}