When called setText(String) from thread (handler) android updated all UI widgets. (e.g. called getView in listview adapters).
handler.post(new Runnable() {
#Override
public void run() {
if (mCurrentTime != null)
mCurrentTime.setText(time);
}
});
(used for showed current audio progress)
How update textview without updated adapters?
Related
I get some error. I really couldn't solve it today :( I get error after set ID data to lblID in FillData() method. It sets ID data properly but lblTitle and lblPrice always returns error like "Only the original thread that created a view hierarchy can touch its views" and program stops running.
Note : This is not my original code. I just minimized it to be more understandable and of course it gives same error like below code. Anyway in FillData() method i get data from wcf service and it returns data properly. i tried runonuithread but it didn't make any sense. Also if i write the code outside of the thread it doesn't fill the controls. Because it's originally gets the data from wcf service.
public class MainActivity extends AppCompatActivity {
LinearLayout lytData;
TextView lblTitle, lblID, lblPrice;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lytData = (TextView)findViewById(R.id.lytNewData);
lblID = (TextView)findViewById(R.id.lblID);
lblTitle = (TextView)findViewById(R.id.lblTitle);
lblPrice = (TextView)findViewById(R.id.lblPrice);
new Thread() {
public void run() {
FillData();
}
}.start();
lytData.setOnTouchListener(new OnCustomTouchListener (context) {
#Override
public void ToLeft() {
new Thread() {
public void run() {
FillData();
}
}.start();
}
#Override
public void ToRight() {
new Thread() {
public void run() {
FillData();
}
}.start();
}
});
}
void FillData() {
lblID.setText("aaa");
lblTitle.setText("aaa");
lblPrice.setText("aaa");
}
The problem is you're trying to update the UI in another thread, but the UI can only be updated in the UI thread. If you're simply updated the UI as your code is showing then you should remove the calls from FillData from the secondary thread, use a secondary thread if you're doing heavy loading inside FillData() otherwise you're better off updating the UI directly in the UI thread:
So instead of doing this:
new Thread() {
public void run() {
FillData();
pd.cancel();
}
}.start();
Just simply call FillData(); outside the new thread.
You can also call runOnUiThread to bring the update to the ui thread:
getActivity().runOnUiThread(new Runnable() {
public void run() {
FillData();
}
});
If your code inside FillData is mixed with heavy load code, then you can bring the runOnUiThread method to inside the FillData and move only the UI update code to runOnUiThread.
If you still want to keep your code the way it is you can "post" changes from your secondary thread like this:
viewElement.post(new Runnable() {
public void run() {
//update UI
}
});
}
viewElement is any UI element that extends from View.
I'm trying to use SocketIO in my Android app to communicate with the server.
Here's my code:
socket = IO.socket("server-address");
socket.connect();
socket.on("init", new Emitter.Listener()
{
#Override
public void call(Object... args)
{
handleResult(args[0].toString());
}
});
I'm unable to update the UI from the call function since it is running in the same thread as the UI (my understanding of the issue).
I've tried using an AsyncTask as well but it moves onto doInBackground before the "call" has completed.
How do I update the UI from within this call function? Or how do I send some data out of it?
You cannot change UI elements from a non-UI thread. Use runOnUiThread to Update UI.
runOnUiThread(new Runnable(){
#Override
public void run(){
// Updat UI here
}
});
Another way to update UI is to Use Handler.
private void updateUI(final String stringData) {
new Handler().post(new Runnable() {
#Override
public void run() {
// Updat UI here
}
});
}
I am trying to remove item from list and notifyItemRemoved() method it is not working it gives array index out of bound exception by removing last item and if I remove item from middle its also remove very next item to it but if put the code outside the thread its working fine
there is my code
Runnable runnable = new Runnable() {
#Override
public void run() {
int progress = 0;
ArrayList<MediaFileObject> selection = localDatabase.getAllMediaObjectsOfID(list.get(selectedAlbum).getId());
for (MediaFileObject obj : selection) {
if (searializeableTasks.isCancelled())
break;
localDatabase.moveMediaObjectToTrash(obj);
progress++;
if (searializeableTasks.isCancelled())
sendProgressToHandle(-101);
else
sendProgressToHandle(progress);
}
if (!searializeableTasks.isCancelled())
localDatabase.deleteAlbum(list.get(selectedAlbum).getId());
Handler handler = new Handler(getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
list.remove(selectedAlbum);
savedAlbumAdapter.notifyItemRemoved(selectedAlbum);
}
});
}
};
searializeableTasks.startTasks(localDatabase.getAllMediaObjectsOfID(list.get(selectedAlbum).getId()).size(), runnable);
but if put all this code inside main thread(Class) its working fine as expected I am putting my code here I want to show my custom progress dialog there for after completion I want to update my RecyclerView can someone please help me. What is wrong in my code? or Why it is not working in separate thread?
Call notify on main thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
savedAlbumAdapter.notifyItemRemoved(selectedAlbum);
}
});
Or
yourrecyclerView.post(new Runnable() {
#Override
public void run() {
savedAlbumAdapter.notifyItemRemoved(selectedAlbum);
}
});
use only
notifyDataSetChanged();
It will work.If you use notifyItemRemoved() after remove() then it would again try to remove next position , so Exception arises.
In a Fragment I have this Thread that have to refresh the text of a
TextView. The problem is that after setText() (the text is set in fact if I log TextView.getText() it returns the text changed) the screen the text is always the same. It change only if a add a view to the Fragment's view.
This is the code,
Thread time = new Thread() {
public void run() {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
while(true) {
TextView.setText("some text");
// i tried also to use TextView.invalidate()
}
});
}
};
}
Remove while(true), you are blocking the UI thread with that
I am using a list view. In which i change the content or add contents when scroll. It works fine but if i navigate 2 or three times from that page, it gives an error.
The Error is:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131230910, class android.widget.ListView) with Adapter.
#Override
public View getView(final int position, View convertView, ViewGroup arg2)
{
Log.e("vec pos", ""+position);
if(position == vectProductBySearch.size()-1 && scrollState == 0 && vectProductBySearch.size()>8)
{
Log.e("vec pos", "in if()");
if (progDialog != null && progDialog.isShowing())
progDialog.dismiss();
progDialog = ProgressDialog.show(ProducyBySearch.this, "",
"Loading... Please wait..", true);
new Thread(new Runnable()
{
#Override
public void run()
{
SearchByCatagory.startIndex= SearchByCatagory.startIndex+10;
post.getProductBySearch(AppsConstants.email, AppsConstants.password, AppsConstants.AuthenticationToken, SearchByCatagory.CatagoryId, SearchByCatagory.description, SearchByCatagory.brand, SearchByCatagory.rating, AppsConstants.UserNum, SearchByCatagory.startIndex);
runOnUiThread(new Runnable()
{
public void run()
{
deafaultAdapter.refresh(AppsConstants.vectProductBySearch);
if (progDialog != null && progDialog.isShowing())
progDialog.dismiss();
}
});
}
}).start();
Use a handler to force any updates from background threads to occur within the UI thread. UI's in nearly all environments/languages don't support changes from other threads
Make sure you are using the UiThread to modify the content of the list and when the list content changes do not forget to call youradapter.notifyDataSetChanged().
outside from the ui-thread you can do ui-operations using post.
just create a new inline runnable-object and add your code to the run()-method.
its not that beatiful but helps in most cases.
example:
view.post(new Runnable() {
#Override
public void run() {
view.scrollTo(0, 0));
}
});