I've been trying to connect to a server to retrieve some data. First thing came to my mind was to create a thread to connect asynchronously.
new Thread(new Runnable() {
#Override
public void run() {
// retrieve data
}
}).run();
But the weird thing is that the thread I created worked synchronous with UI thread and I got a network exception so I ended up using AsyncTask. Do you guys know what could cause a thread to work non asynchronously with the UI thread? My class extends to a fragment.
Your must start your thread with start() and not run() in order to start the new thread:
new Thread(new Runnable() {
#Override
public void run() {
// retrieve data
}
}).start();
Related
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 need to run something inside my extends Application class on the UI thread
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
//I need to run code here on the main thread
}
}, 1000);
do I need to pass the activity? It will be difficult since I am calling it from multiple activities
Methods called by Android in the Application class already run on the UI thread (a.k.a 'main' thread).
When in doubt you can use Thread.currentThread() to find out.
Remember to avoid doing costly operations on the main thread.
You need to call runOnUiThread
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Log.d("UI thread", "I am the UI thread");
}
});
I have two fragments and I have slide in, slide out transitions between fragments, after my fragment is loaded, I try to fetch data from server and load data into an array adapter, my problem is, I see my fragments freeze between transitions, I use execute to execute my asynctask in background, here is my code, DownloadJson extends to AsyncTask
public void onResume() {
DownloadJson downloadJson = new DownloadJson();
downloadJson.execute("http://somesite.com");
}
How can I start fetching data after fragment is loaded without freezing between transitions, thank you
Just use thread insted using asynctask.
asynctask still work in ui thread.
new Thread(new Runnable() {
#Override
public void run() {
//download jason... after that
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
//you can access to ui here when download is finished...
});
}
}).start();
At first, you can't use any network activity on main UI Thread, you'll get a NetworkException. You can solve this by using new Thread(new Runnable() {....}); , something like this :
DownloadJson downloadJson = new DownloadJson();
Thread t = new Thread()
{
#Override
public void run() {
try {
downloadJson.execute("http://somesite.com");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//move on with the code, and get data from Thread.
t.start();
I'm casting into JSONObject for demo only, you need to set the right cast on your side.
The ios can start a async method,and wait in the main thread with a nsrunloop
while(!iterationDone) {
[runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
//do other stufff
}
with this,the uithread can keep alive,and i can keep the sequence of invoke many async method. it just easily invode like sync method.
public int asyncmethod1{
new Handler.post(new Runnable() {
#Override
public void run() {
// Do something on the UI-Thread
}
});
//while(handler is end)
//return the result
}
public void main(){
int i= asyncmethod1();
i+=asyncmethod2();
}
but this method must be cause the uithread not responsed.
In Android there are two many concepts to handle async tasks and do something on the UI-Thread.
1) The Handler http://developer.android.com/reference/android/os/Handler.html
new Handler.post(new Runnable() {
#Override
public void run() {
// Do something on the UI-Thread
}
});
2) The AsyncTask
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate hreads and/or handlers. http://developer.android.com/reference/android/os/AsyncTask.html
A usage example for the AsyncTask is at the developer site of Android.
I have one function which queries a network server with a few "ping pongs" back and forth, and have written a custom handler to handle the message communication between my main UI thread and the communication thread (I was using AsyncTask for this, but as the program got more complex, I have decided to remove the communication code to its own class outside of the main activity).
Triggering a single instance of this thread communication from onCreate works perfectly, no problem.
I want this query to run on a regular timed basis -- in the background -- for the entire time the app is in use, so I've set up another thread called pollTimer, which I'm trying to use to call the OTHER thread at a regularly scheduled basis.
Obviously, it's crashing, or I wouldn't be posting this.
Is there a way to get a thread within a thread? Or put differently, trigger a thread from another thread?
Timer pollTimer = new Timer();
private void startPollTimer(){
pollTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Log.d(TAG,"timer dinged");
//if the following is commented out, this "dings" every 6 seconds.
//if its not commented out, it crashes
threadedPoll();
}
}, 3120, 6000);
}
private void threadedPoll() {
testThread(asciiQueries,WorkerThreadRunnable.typeLogin);
}
edit: it would probably help to include the "testThread" function, which works by itself when called from onCreate, but does not make it when called from the Timer.
"WorkerThreadRunnable" is the massive chunk of code in its own class that has replaced the mess of having AsyncTask handle it inside the main activity.
private Handler runStatHandler = null;
Thread workerThread = null;
private void testThread(String[] threadCommands, int commandType){
if(runStatHandler == null){
runStatHandler = new ReportStatusHandler(this);
if(commandType == WorkerThreadRunnable.typeLogin){
workerThread = new Thread(new WorkerThreadRunnable(runStatHandler,threadCommands, WorkerThreadRunnable.typeLogin));
}
workerThread.start();
return;
}
//thread is already there
if(workerThread.getState() != Thread.State.TERMINATED){
Log.d(TAG,"thread is new or alive, but not terminated");
}else{
Log.d(TAG, "thread is likely deaad, starting now");
//there's no way to resurrect a dead thread
workerThread = new Thread(new WorkerThreadRunnable(runStatHandler));
workerThread.start();
}
}
You seem to be well on the way already - the nice thing about handlers, though, is that they aren't limited to the UI thread - so if you have a Handler declared by one thread, you can set it up to take asynchronous instructions from another thread
mWorkerThread = new WorkerThread()
private class WorkerThread extends Thread {
private Handler mHandler;
#Override
public void run() {
mHandler = new Handler(); // we do this here to ensure that
// the handler runs on this thread
}
public void doStuff() {
mHandler.post(new Runnable() {
#Override
public void run() {
// do stuff asynchronously
}
}
}
}
Hopefully that helps... if I'm totally off base on your problem let me know
Wots wrong with a sleep() loop? Why do you have pagefuls of complex, dodgy code when you could just loop in one thread?