multithreading - How do I correctly pass information from a long-running thread to the UI thread in Android? -
my app has chat feature. when app first starts up, spawn listener thread listen incoming data:
public class mainactivity extends appcompatactivity { public static linkedlist<message> chatlist; protected void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); chatlist = new linkedlist<message>(); handler listenerthreadhandler = new handler(); mylistener mylistener = new mylistener(listenerthreadhandler, mainactivity.this); thread listenerthread = new thread(mylistener); listenerthread.start(); } }
my chat feature fragment/tab within main activity. has standard window viewing chat, plus edittext , button sending chats:
<linearlayout android:id="@+id/chat_window" android:orientation="vertical"> <listview android:id="@+id/received_chats" android:stackfrombottom="true" android:transcriptmode="alwaysscroll"> </listview> <linearlayout android:id="@+id/control_window" android orientation="horizontal"> <edittext android:id="@+id/chat_entry_window" /> <button android:id="@+id/send_chat_button" android:text="send" /> </linearlayout> </linearlayout>
when send text, add main linkedlist.
public class chat extends fragment { private view rootview; @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate){ rootview = inflater.inflate(r.layout.chat, container, false); return rootview; } @override public void onviewcreated(view rootview, bundle, savedinstancestate){ super.onviewcreated(rootview, savedinstancestate); displaychats(); } @override public void onresume(){ super.onresume(); displaychats(); } @override public view getview(){ button sendchatbutton = (button) rootview.findviewbyid(r.id.send_chat_button); sendchatbutton.setonclicklistener(new view.onclicklistener(){ @override public void onclick(view v){ edittext chatentrywindow = (edittext) rootview.findviewbyid(r.id.chat_text_entry); // add chat linkedlist mainactivity.chatlist.add(chatentrywindow.gettext().tostring()); } }); } public void dispalychats(){ final arrayadapter adapter = new customarrayadapter(getactivity, r.layout.line_of_chat_text, mainactivity.chatlist); final listview list = (listview) rootview.findviewbyid(r.id.received_chats); list.smoothscrolltoposition(list.getcount() - 1); } }
i add incoming chats app in listener
public class mylistener implements runnable { handler myhandler; context mycontext; public mylistener(handler myhandler, context mycontext){ this.myhandler = myhandler; this.mycontext = mycontext; } @override public void run(){ listenforchats(); } public listenforchats(){ // here want add chats main list. mainactivity.chatlist.add(received_chat); } }
what want able pass text received listenerthread ui thread inserted linkedlist. know need because error every in app:
java.lang.illegalstateexception
the content of adapter has changed listview did not receive notification.
make sure content of adapter not modified background thread, ui thread.
i have used handler before, don't know if using correctly here. in past, have passed in layout element (e.g., textview, imageview, etc.) , have updated handler.
in listener thread, changed
mainactivity.chatlist.add(received_chat);
to
myhandler.post(new runnable(){ @override public void run(){ mainactivity.chatlist.add(received_chat); } });
my chats still getting added main linkedlist, don't know if different way did or not. how know if have passed data ui thread?
so, how correctly pass data listener thread ui thread adding linkedlist?
Comments
Post a Comment