Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First, I'll say I'm learning this myself, but I've managed to get this exact setup working in a prototype. If anyone sees something that should be changed to work better in Android, by all means let me know.</p> <p>Second, I'm using empty messages so that we have code that would actually work. I assume that creating message objects is straight forward enough.</p> <h1><strong>Part 1 - UI to Network Thread</strong></h1> <p>As far as I have seen, Handler is the answer you need, but it's not the whole picture. Deucalion's comment about Looper is where you need to look next.</p> <p><a href="http://developer.android.com/reference/android/os/Looper.html" rel="nofollow">http://developer.android.com/reference/android/os/Looper.html</a></p> <pre><code>class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } } </code></pre> <p>This setup is counter intuitive at first, you need to create the Handler object between the <code>Looper.prepare()</code> and <code>Looper.loop()</code> calls, inside your <code>run()</code> method. I don't know the magic behind the scenes, haven't had a chance to get that far down the rabbit hole.</p> <p><strong>Important Note</strong>: The sample shows an anonymous Handler() being created. I highly recommend subclassing Handler in your own class and then using an instance of that. It's just a matter of reusability, a lot of network code ends up being the same.</p> <p>So, rename <code>LooperThread</code> to <code>NetworkThread</code>, or whatever you'd like it to be, and put your connection code in the <code>run()</code> method, but outside the <code>Looper.prepare() / Looper.loop()</code> block (again I don't know how the magic works, so I'm just assuming this is better to do than to have it inside).</p> <pre><code>// process incoming messages here </code></pre> <p>Tends to look like this:</p> <pre><code>switch(msg.what) { case 1: break; default: break } </code></pre> <p>The LooperThread example has <code>public Handler mHandler;</code> but I prefer to make the handler private and create a method to return it. I do this just to prevent the handler from being accessible until after the network connection is established. No connection, nothing to do with the messages.</p> <p>So, somewhere in your activity code you create the <code>NetworkThread</code> object, run it, and then get the Handler from it.</p> <pre><code>NetworkThread network = new NetworkThread(); new Thread(network).run(); //Handler networkHandler = network.handler; Handler networkHandler = network.getHandler(); </code></pre> <p>Then you just send messages to that handler as needed.</p> <pre><code>networkHandler.sendEmptyMessage(1); </code></pre> <hr> <h1>Part 2 - Network Thread to UI</h1> <p>There are a couple of different ways to handle this. You can create a handler inside the Activity class. All activities have a Looper already setup, so calling Looper.prepare and Looper.loop seem to cause problems.</p> <p>In my code I create a handler in the <code>onCreate()</code> method, and then I pass it into my <code>NetworkThread</code> object. There may be better places to create this Handler, I don't know what will happen if your application is suspended and then started again later with <code>onResume()</code> or <code>onRestart()</code></p> <pre><code>public NetworkThread(Handler mainHandler) { this.mainHandler = mainHandler; } </code></pre> <p>Then anywhere else I need to send a message to the UI:</p> <pre><code>this.mainHandler.sendEmptyMessage(1); </code></pre> <p>I prefer this method because the Handler code, that does the actual work, either exists in the classes the actually respond to the message (using the anonymous Handler objects) or in Handler subclasses that may be in the same package.</p> <p>You could also pass in the <code>Activity</code> or a <code>View</code> to the network thread and from that call <code>runOnUIThread(Runnable)</code>, but that requires you pass in a Runnable. So the code that is meant to work on the UI is being written or referenced in the Networking classes.</p> <hr> <h2>Update</h2> <p>You could also use a Service for this. The method above works when the Activity and the Networking have the same life span. If we only need network connection while the Activity is active.</p> <p>If you need network connectivity beyond the life of the Activity, in a music streaming app for example, then going with a Service would be a better choice. It didn't seem like this was specifically what you were looking for the question.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload