How to deserialize Activity object in a background thread? [duplicate] - android

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
I have a problem with using Java Serialization mechanism in Android. It works well when invoked from the UI thread, but when I try to use it from some background thread I get:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Because of project nature I cannot deserialize everything in UI thread (also it should be possible to do it in background, so the UI will not stop responding).
BTW. Same thing happens when I try to deserialize something in background using SimpleXML.
So now we do deserialization (both XML and Java serialization) from UI thread which cannot be used everywhere.
Can anyone shed some light on this issue?
EDIT:
I'm using the following code to deserialize an object, it works well when called from UI thread.
public Object getObject(String key) throws InvalidClassException {
Object result;
try {
FileInputStream fileIn = context.openFileInput(getPath(key));
ObjectInputStream in = new ObjectInputStream(fileIn);
result = in.readObject();
in.close();
fileIn.close();
} catch (InvalidClassException e) {
throw new InvalidClassException(e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return result;
}
EDIT 2
As mentioned in EJP comment below, I'm deserializing an Activity object. So I'm changing my questuion to: How to deserialize Activity object in a background thread?
Not deserializing this object is an option that I'd rather avoid, because of performance issues (XML deserializes in about 4s while binary deserialization is less then 0.5s). I know that it would be possible to redesign our application, but due to project constraints, and it's extreme and unnecessary complexity, that's not really an option. Every bigger change is extremely painful.
So when issue is little clearer - does anyone have some ideas?
Thanks for any suggestions.

Try and call Loooper.Prepare(); before your code and
Looper.Loop(); after, workd for me.
Something like :
Looper.Prepare();
//your code
Looper.Loop();

you cannot do ui operations in any other thread
all ui operations should be on mainthread
you can use this
runOnUiThread(new Runnable() {
#Override
public void run() {
code here
}
});

Related

How to run a code when all threads are done

I am new to threading and i went through many post in stack overflow and find many solution for my problem but i am not sure which one is best for which condition.
First thing first, my problem is that i want to update one JSON file
when all threads are done with the bitmap generation at a specific path so
that i can get that all those image and update JSON file. So in
simple word my i want to run some code when all thread are done with it
execution and major requirement is that i don't want my main to be blocked because of this.
What i have found out
thread. join
excutorServive
android-priority-jobQueue (link)
Mutex in threadpool ( also let me know if any other is there)
I am confused which one is the best way to tackle my problem. if any
android expert out there can summarise that for following the two
scenerio what is the best available in android.
wait till when all thread completes
don't wait and get informed when all completes
You can have counter for your threads, after each thread is complete check how many have already completed, if not all completed, increment the number of completed threads and the last thread to complete will then run the piece of code.
You can do it like this.
In your thread:
private Runnable runnableThread= new Runnable() {
#Override
public void run() {
try {
if (lastThreadDone){
handler.sendEmptyMessage("SUCCESS");
}
}
catch (Exception ex) {
throws ex;
}
}
};
lastThreadDone is boolean which will become true if the process is done, this is base on how you implement it.
then in you handler:
#SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
try {
switch (msg.what) {
case "SUCCESS": {
// your code here
break;
}
case "FAIL":
break;
default:
break;
}
}
catch (Exception ex) {
throw ex;
}
super.handleMessage(msg);
}
};
I would use a completion service and then poll until all tasks are finished. When they are done, the json file gets updated. The problem is that you need to do this async or you risk to block the ui. Therefore I would encapsulate the work with the completion service inside an intent service. If you need to update the ui you then can post local broadcasts from the intent service.
Furthermore for you cases
wait till when all thread completes
only do this when you are already on a background thread like intent service or async task
don't wait and get informed when all completes
implies the case above. Do the work async and notify the ui or some listening component with broadcasts, content observers, handlers or the 'onPostExecute' if you are using async task.

Can't fetch objects using QBCusomObjects off of main thread in android

So in my app, I'm trying to fetch some custom objects I've made, and I'm getting this error:
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at com.quickblox.core.server.HttpRequestRunnable$1.<init>(HttpRequestRunnable.java:40)
at com.quickblox.core.server.HttpRequestRunnable.<init>(HttpRequestRunnable.java:40)
at com.quickblox.core.server.ThreadPoolIntentService.execute(ThreadPoolIntentService.java:23)
at com.quickblox.core.server.HttpRequestTask.execute(HttpRequestTask.java:29)
at com.quickblox.core.rest.RestRequest.asyncRequestWithCallback(RestRequest.java:110)
at com.quickblox.core.query.Query.performInBgAsyncWithDelegate(Query.java:115)
at com.quickblox.core.query.Query.performAsyncWithCallback(Query.java:218)
at com.quickblox.customobjects.QBCustomObjects.getObjects(QBCustomObjects.java:532)
Originially, I was calling the getObjects method from a separate thread I spawned to do the network communication, both because doing it on the UI thread seemed like a bad idea, and because when I tried to do it on the UI thread I got a NetworkCommunicationOnMainThread exception.
Since the separate thread didn't work, I put the request in an AsyncTask to see if that would help, and it didn't change anything.
The code for the request is below
final QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder();
try {
Log.i(classTag, "Attempting to get UserID");
requestBuilder.eq("User_ID", ""+ QBAuth.getSession().getUserId());
} catch (QBResponseException e) {
Log.e(classTag, "Failed to get UserID for current user");
e.printStackTrace();
return null;
}
QBCustomObjects.getObjects("Listing", requestBuilder, new QBEntityCallbackImpl<ArrayList<QBCustomObject>>() { ...}
Any help would be greatly appreciated. Thanks!
This request works in a separate thread already
QBCustomObjects.getObjects("Listing", requestBuilder, new QBEntityCallbackImpl<ArrayList<QBCustomObject>>() { ...}
so you don't need to wrap it
there is also a possibility to use 'sync' requests

What is the use case for a Android Future?

For context, I am an Android developer who is familiar with using AsyncTask's but has recently started working on a project which is heavily using Future's. The Futures do not have a callback and require checks on isDone() to determine progress.
I am having trouble understanding what the purpose and use case of Future is in Android. AsyncTask's provide what seems like the same functionality but with in my opinion a better interface which has callbacks built in that enable the client to clearly determine when the async operation is complete without having to constantly check isDone().
What is the use and purpose of a Future in Android, and why would I use Future or FutureTask over an AsyncTask?
The Future is part of the Java API, whereas the AsyncTask is Android specific. In fact, if you take a look at the source code of AsyncTask, you will see that it actually uses a FutureTask for its implementation:
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
mFuture = new FutureTask<Result>(mWorker) {
#Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
The AsyncTask is thus just a helper class for short threading jobs, which also handles some thread pooling. My guess is that the original writers of your project were familiar with Futures, but not with AsyncTask, or generally disliked AsyncTask.
Since I dislike the original AsyncTask implementation due to its Exception handling, I went on a search for a better alternative, and found RoboGuice's SafeAsyncTask. In this implementation, an onException(Exception) callback is available, but RuntimeExceptions get propagated to that callback as well.
I think a NullPointerException should make the app just crash, and I modified this SafeAsyncTask a little while back to do exactly this. The result can be found here.

Do I have to delete threads in Android

I have the following function call from a thread:
Thread Move = new Thread(){
public void run()
{
while(ButtonDown){
UpdateValues();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Move.start();
Will Android delete the thread when the while-loop breaks, or do I have to delete it in some way?
There are two concepts here. One is the thread itself, the thing running in the processor, that has stack memory. The other is the Thread object, which is basically a control panel to access the thread.
The thread has stack memory which is released when the thread dies (run() completes or an exception is thrown, basically). However, the Thread java object stays around until there is no longer a reference to it.
So, let's say you had this:
this.myThread = new Thread(){
public void run()
{
int[] takeUpSomeMemory = new int[10000];
while(ButtonDown){
UpdateValues();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
this.myThread.start();
So you have an instance variable myThread which holds a reference to a Thread you create. When the start method is called, your thread is called and it allocates quite a bit of memory for the variable takeUpSomeMemory. Once the run() method dies by completing execution or throwing an exception the memory for takeUpSomeMemory is garbage collected. The memory for this.myThread is retained until the instanceVariable is set to nil or the object of the enclosing class is garbage collected.
When you return from the thread, you have essentially stopped it, so no, you don't need to do anything specific to delete the thread. Please keep in mind that this is not a good use case for threads in Android. If you are updating the UI from a non-UI thread you will most likely get the framework complaining at you. Instead, you should read a few tutorials on AsyncTask and move to that model, as it will let you update the UI.

how do you read text files off the internet in Android 4.0.3

I am a relatively new Android programmer and I was wondering how you could get read text off the internet in 4.0.3. I keep finding code that gives me a Network on Main exception: http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html and was wondering if anyone could provide me some sample code to get around this, for reference I got the code I tried to use here: http://android-er.blogspot.com/2011/04/read-text-file-from-internet-using-java.html. Thanks a lot.
In Honeycomb and Ice Cream Sandwich (i.e. Android 3.0+) , you cannot connect to the internet in the main thread (onCreate(), onPause(), onResume() etc.), and you have to instead start a new thread. The reason why this has changed is because network operations can make the app wait for a long time, and if you're running them in the main thread, the whole application becomes unresponsive. If you try to connect from the main thread, Android will throw a NetworkOnMainThreadException.
To bypass this, you can run networking code from a new thread, and use runOnUiThread() to do things in the main thread, such as update the user interface. Generally, you can do something like:
class MyActivity extends Activity {
public onCreate(Bundle savedInstanceState) {
super.onCreate();
// Create thread
Thread networkThread = new Thread() {
#Override
public void run() {
try {
// this is where your networking code goes
// I'm declaring the variable final to be accessible from runOnUiThread
final String result = someFunctionThatUsesNetwork();
runOnUiThread(new Runnable() {
#Override
public void run() {
// this is where you can update your interface with your results
TextView myLabel = (TextView) findViewById(R.id.myLabel);
myLabel.setText(result);
}
}
} catch (IOException e) {
Log.e("App", "IOException thrown", e);
}
}
}
}
}
You need to complete an HTTP Request. There are a lot of examples available on line. Try here for starts.

Categories

Resources