Android Send Data From Main Ui Thread To Another Thread
Solution 1:
You can't do it this way. You've created your second Thread by using HandlerThread
. A HandlerThread
is a Thread
that has a Looper
. So that is what is going on in the run()
method of HandlerThread
. It is running the looper loop. That means that the run()
method in the HandlerThread
will only complete when the Looper
exits.
In your initThread()
method you wrote:
@Overridepublicvoidrun() {
super.run(); // <-- This call runs the Looper loop and doesn't complete!!try{
handler = newWorkerHandler(getLooper());
}catch(Exception e){
e.printStackTrace();
}
}
You can see that your overridden run()
method first calls super.run()
. This runs the looper loop and doesn't complete. So the rest of your code in initThread()
never executes.
If you want to use a HandlerThread()
then you can't mess with its run()
method. If you want it to do stuff for you then you'll need to post messages (or Runnable
s) to it, and do your work there. Here's an example:
HandlerThreadhandlerThread=newHandlerThread("myHandlerThread");
handlerThread.start();
// Now get the Looper from the HandlerThread so that we can create a Handler that is attached to// the HandlerThread// NOTE: This call will block until the HandlerThread gets control and initializes its LooperLooperlooper= handlerThread.getLooper();
// Create a handler attached to the background message processing thread
handler = newHandler(looper, this);
Now you can post messages and Runnable
s to the "handler". In this example, the messages will be processed by an overridden handleMessage()
method of the creating class.
EDIT: Provide code example for the Handler callback
You can use your WorkerHandler
class to handle the callbacks if you modify it like this (I've changed the name to Worker
because it isn't really a Handler
, it just implements the Handler.Callback
interface):
publicclassWorkerimplementsHandler.Callback {
protected Socket socket;
protected BufferedWriter writer;
publicWorker()throws Exception{
this.socket = newSocket("192.168.1.7", 5069);
this.writer = newBufferedWriter(newOutputStreamWriter(this.socket.getOutputStream(), "utf-8"));
}
public BufferedWriter getWriter(){
returnthis.writer;
}
public Socket getSocket(){
returnthis.socket;
}
@OverridepublicvoidhandleMessage(Message msg) {
Drawdraw= (Draw) msg.obj;
if (draw != null){
if (getWriter() != null){
try{
getWriter().write(DrawUtil.toJson(draw)+"\n");
getWriter().flush();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
Now you need to create an instance of this Worker
class and pass it as the callback argument when you create the Handler
. In your activity do:
HandlerThreadhandlerThread=newHandlerThread("myHandlerThread");
handlerThread.start();
Looperlooper= handlerThread.getLooper();
// Create an instance of the class that will handle the messages that are posted// to the HandlerWorkerworker=newWorker();
// Create a Handler and give it the worker instance to handle the messages
handler = newHandler(looper, worker);
Solution 2:
You could solve it using standard Java ways for consumer / producer problems, i.e. a BlockingQueue
consumed by a thread and any amount of threads that produce data.
publicclassSendingWorker {
privatefinal BlockingQueue<Draw> sendQueue = newLinkedBlockingQueue<Draw>();
privatevolatile Socket socket;
publicvoidstart() {
thread.start();
}
publicvoidstop() {
// interrupt so waiting in queue is interrupted
thread.interrupt();
// also close socket if created since that can block indefinitelySocketsocket=this.socket;
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// adding to queues is thread safepublicvoidsend(Draw draw) {
sendQueue.add(draw);
}
privatefinalRunnabletask=newRunnable() {
@Overridepublicvoidrun() {
try {
socket = newSocket(InetAddress.getLocalHost(), 8000);
OutputStreamout= socket.getOutputStream();
while (true) {
Drawdraw= sendQueue.take();
out.write(draw);
out.flush();
}
} catch (Exception e) {
// handle
} finally {
// cleanup
}
}
};
privatefinalThreadthread=newThread(task);
}
Solution 3:
You can get values through broadcast receiver......as follows, First create your own IntentFilter as,
Intent intentFilter=newIntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");
Then create inner class BroadcastReceiver as,
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
/** Receives the broadcast that has been fired */
@Override
publicvoid onReceive(Context context, Intent intent) {
if(intent.getAction()=="YOUR_INTENT_FILTER"){
//HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW///////////String receivedValue=intent.getStringExtra("KEY");
}
}
};
Now Register your Broadcast receiver in onResume() as,
registerReceiver(broadcastReceiver, intentFilter);
And finally Unregister BroadcastReceiver in onDestroy() as,
unregisterReceiver(broadcastReceiver);
Now the most important part...You need to fire the broadcast from background thread to send values..... so do as,
Intent i=newIntent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);
....cheers :)
Post a Comment for "Android Send Data From Main Ui Thread To Another Thread"