06-06 23:50:28.340 27670-27706/mys.timer E/AndroidRuntime: FATAL EXCEPTION: Timer-0
Process: mys.timer, PID: 27660
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
My code:
protected void onCreate(Bundle savedInstanceState) {
public void run() {
new Timer().scheduleAtFixedRate(new TimerTask(){
#Override
public void run(){
status.setText(getResources().getString(R.string.timercount));
status.setTextColor(Color.parseColor("#990000"));
}
}
}
Please tell me how can i avoid my app from closing itself
Android’s UI components are not thread safe so one may need to update Views or other UI components from a secondary thread when returning from an asynchronous database query or a web service call. If you run the code from a secondary thread you might see that the code crashes almost on each try.
runOnUIThread Activity’s method
yourActivity.runOnUiThread(new Runnable(){
public void run() {
// UI code goes here
}
});
I hope that it helps you.
Related
I am getting data from a RoomDB then using a custom adapter to present this data in a recycler view.
But I am occasionally getting this error, "Only the original thread that created a view hierarchy can touch its views."
This is where the error happens
((MyActivity)context).runOnUiThread(new Runnable() {
#Override
public void run() {
setData();
}
});
I don't understand what is from as I am using the context of the activity the recycler view is in and then running the thread on the UI thread.
You have to move the task that updates the UI onto the main thread.
Try like this
runOnUiThread(new Runnable() {
#Override
public void run() {
// UI Updates
}
});
Sorry everyone this has been asked a few times but I just do not understand any of the answers because most are about timed UI updates. So I have a backgroundTasks thread that is called when my app first starts(Does network connections so..I think that's how you do it?)
public class MainActivity extends ActionBarActivity {
String data[][];
int arrayPosition = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
runBackgroundTask();
}
Here is my thread..
public void runBackgroundTask(){
new Thread(new Runnable() {
public void run() {
data = pullSchedule(data);
updateUI(data,arrayPosition);
}
}).start();
}
All it does is call a method pullSchedule which updates a 2D array with a webcrawler. So my problem comes when I call the updateUI method which is also used by two buttons to cycle through the array data which work perfectly fine. It's just when the thread first runs if I try to update the UI I get an error.
public void upDateUI(String data[][], int arrayPosition){
TextView gameTime =(TextView)findViewById(R.id.txtDate);
//more but deleted to save space :)
}
I have researched why I cannot update the UI from the background thread but I don't understand how to fix this? I thought about putting that entire method into the runOnUiThread(new Runnable()but then I believe my data and arrayPosition have to be declared final because of an inner class..First Android app just lost. Thanks for any help.
you can use asyntask for this from which you can update ui
public myAsyn extends AsyncTask<Void,Void,Void>
{
#Override
protected String doInBackground(Void... params) {
data = pullSchedule(data);
return null;
}
#Override
protected void onPostExecute(String result) {
updateUI(data,arrayPosition);
}
}
doInBackground runs on seperate thread whereas onPostExecute runs on Ui thread therefore you can update UI from there.
You are on the right track. The reason your app is crashing is because you are attempting to update a UI element off of the UI thread. To avoid this, you can either do as RichS suggested, and use an AsyncTask which will execute onPostExecute() on the UI thread, or surround your updateUI() call in your background thread with runOnUiThread(new Runnable() {....
I have following code to run a function in another thread:
Button buttonb = (Button) this.findViewById(R.id.buttonb);
buttonb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
…
progressBar.setVisibility(View.VISIBLE);
Thread thread = new Thread() {
#Override
public void run() {
matrixOperation(sourcePhoto);
}
};
thread.start();
progressBar.setVisibility(View.INVISIBLE);
…
}
});
But on running i am getting this error:
Can't create handler inside thread that has not called Looper.prepare()
I searched and found that one reason for this error is “You cannot execute an AsyncTask from a background thread. See the "Threading Rules" section of” But this is not background thread I am calling it from my Main Activity.
Please tell me how I can fix this.
The Handler class uses Loopers to perform its scheduling, and threads that have just been created does not have an associated looper – hence the error.
As you have not provided the handler creation code, I'm assuming you want to call code on the main thread. In this case, create the Handler as follows:
Handler handler = new Handler(Looper.getMainLooper());
Anything scheduled to run on that Handler will execute on the main Looper, which is running on the main thread.
I am using a freind to download a picture and set in the ImageView; however, I get this error:
Only the original thread that created a view hierarchy can touch its views.
This is my code.
ImageView profilePicture =....
Thread thread = new Thread() {
#Override
public void run() {
profilePic.setImageBitmap(image_profile);
}
};
thread.start();
The image_profile Bitmap is a valid Bitmap file. (I checked it via debug.)
This thread is running in the OnCreate method.
You cannot update your UI directly from the Thread. Instead, use runOnUiThread() or equivalent.
Replace this:
profilePic.setImageBitmap(image_profile);
With this:
YourActivityName.this.runOnUiThread(new Runnable() {
#Override
public void run() {
profilePic.setImageBitmap(image_profile);
}
});
You cannot update ui on another thread. Update ui on the main ui thread as below
Thread thread = new Thread()
{
#Override
public void run() {
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
profilePic.setImageBitmap(image_profile);
}
});
}
};
thread.start();
The problem isn't about the Bitmap. The problem is that you are trying to do UI stuff in a separate Thread. With the code you've given, there is no reason for the Thread. Remove the Thread. If you are doing other things that you aren't showing then you can use runOnUiThread or an AsyncTask and update the ImageView in any method other than doInBackground() as it doesn't run on the UI
I have a simple function that shows loading spinner while fetching data (usually takes 7 seconds or so)
private void load_data(View v)
{
task_complete = false;
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(false);
progressBar.setMessage("Fetching data ...");
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressBar.show();
try
{
Log.v("thread", "Starting thread");
new Thread(new Runnable()
{
public void run()
{
while(!task_complete)
{
fetch_data();
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
progressBar.dismiss();
}
}).start();
Log.v("thread", "Thread finished successfully");
}
catch(Exception e)
{
Log.v("thread", "fail "+e.toString());
}
}
The problem I have is that the function gets called by onClick via
load.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
load_data(v);
show_data(v); // shows the data on a spinner
}
});
And when I press the load button the second time I get an error. My log does show
Starting thread
Thread finished successfully
But somehow the app dies with an error saying
03-27 02:48:39.282: E/AndroidRuntime(956): Uncaught handler: thread Thread-9 exiting due to uncaught exception
03-27 02:48:39.293: E/AndroidRuntime(956): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-27 02:48:39.293: E/AndroidRuntime(956): at android.view.ViewRoot.checkThread(ViewRoot.java:2683)
I would greatly appreciate it if someone can show me or explain to me what causes the error
The problem is that your progressBar.dismiss(); is executed in another thread, to make it run in UI thread, do this:
runOnUiThread(new Runnable() {
#Override
public void run() {
progressBar.dismiss();
}
});
ProgressDialog is a View and you can access it in the UI thread (or main thread) only. Use AsyncTask instead of threads.
EDIT
This official link will help you get the hang of AsyncTask. The thing to remember is doInBackground() method runs in separate thread where you should put your data loading method i.e. fetch_data(). Once the method completed execution, onPostExecute() will get called, which will run on UI thread, where you can dismiss the dialog. You can start the dialog in the onPreExecute() method.
Though in this context you do not need the onProgressUpdate() method, but just FYI, it is used to update the Views in UI thread while the loading is still working using publishProgress() call (In case you use the AsyncTask in future).
PS: Only the doInBackground() method runs in separate thread, every other method runs in UI thread. The rule about not accessing the View in any other thread except the UI one, still applies here.