Background tasks without using service - Android - java

I am working on an application which has 5- 6 activities where user is involved. Some data will be generated during this and is saved into Database.
I need to upload/sync these data between server ( I use KSOAP2 ). But this should happen behind. Even if the user is jumping between activities, it should not get affected. But when I quit the app I don't want this process to continue.
Is Android Service the only way to do this? What would be the best option?

You can use Async Task
http://developer.android.com/reference/android/os/AsyncTask.html. Have a look at the documentation under the heading The 4 steps.
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.
In your activity after setContentView()
pd= new ProgressDialog(this);
pd.setTitle("Making Soap Request");
new SoapRequestTask().execute();
private class SoapRequestTask extends AsyncTask<VOid, Void, Void> {
protected void onPreExecute()
{
pd.show();
}
protected SoapObject doInBackground(Void... params) {
// TODO Auto-generated method stub
//Soap request. do not update ui here
return null;
}
protected void onPostExecute(Void param)
{
//update ui here
pd.dismiss();
}
An alternative to asynctask is Robospice.https://github.com/octo-online/robospice.
You can get started with robopice here. https://github.com/octo-online/robospice/wiki/Starter-Guide.
A sample of robospice at https://play.google.com/store/apps/details?id=com.octo.android.robospice.motivations&feature=search_result.
Some of the features of robospice.
1.executes asynchronously (in a background AndroidService) network requests (ex: REST requests using Spring Android).
2.is strongly typed ! You make your requests using POJOs and you get POJOs as request results.
3.enforce no constraints neither on POJOs used for requests nor on Activity classes you use in your projects.
4.caches results (in Json with both Jackson and Gson, or Xml, or flat text files, or binary files, even using ORM Lite).
5.notifies your activities (or any other context) of the result of the network request if and only if they are still alive
6.no memory leak at all, like Android Loaders, unlike Android AsyncTasks notifies your activities on their UI Thread.
7.uses a simple but robust exception handling model.

I think Async task is what you are looking for ...http://developer.android.com/reference/android/os/AsyncTask.html

No, you can use an AsyncTask. documentation: http://developer.android.com/reference/android/os/AsyncTask.html

Related

Where should network related task like api calling be be placed in Activity lifecycle?

I'm creating an android app which has single activity for now. This activity calls an api to get JSON response and populate the Fragments. Once the JSON response is received I am updating the data set and notifying adapter. Currently the JSON request is called in onCreate method.
Similarly in each fragment I need to load image from network so I am wondering will it too should be put in onCreateView or someplace else?
I'm interested in knowing what is the best practice to achieve this.
The best practise is to use an asynchronous event when doing networking stuff, because depending on your server response time andd on your network speed, you will maybe get the response late and that block your UI and that's not good.
I suggest you integrate AsyncTask when calling your API.
Here is an example
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(String... urls) {
try {
//here you make your api call and json parsing
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
}
And you call your request in your onCreate like this
JSONAsyncTask task=new JSONAsyncTask();
task.execute();
Take a look at docs for further information https://developer.android.com/reference/android/os/AsyncTask
It's fine doing network call in onCreate, put my two cents in i suggest you this good practices that i use.
-Study network call and try to estabilish how many time it takes and if result is needed for UI thread, For long operations AsyncTask should not be used
From documentation
AsyncTasks should ideally be used for short operations (a few seconds
at the most.) If you need to keep threads running for long periods of
time, it is highly recommended you use the various APIs provided by
the java.util.concurrent package such as Executor, ThreadPoolExecutor
and FutureTask.
-Never reinvent the wheel you could use a lot of libray for network operations like:
Retrofit
OkHttp
Volley
AndroidFastNetworking
-Always handle error! There is nothing more annoying than an infinite loader caused by some connection error, check internet connection with BroadCast Receiver

Android Architecture Components network threads

I'm currently checking out the following guide: https://developer.android.com/topic/libraries/architecture/guide.html
The networkBoundResource class:
// ResultType: Type for the Resource data
// RequestType: Type for the API response
public abstract class NetworkBoundResource<ResultType, RequestType> {
// Called to save the result of the API response into the database
#WorkerThread
protected abstract void saveCallResult(#NonNull RequestType item);
// Called with the data in the database to decide whether it should be
// fetched from the network.
#MainThread
protected abstract boolean shouldFetch(#Nullable ResultType data);
// Called to get the cached data from the database
#NonNull #MainThread
protected abstract LiveData<ResultType> loadFromDb();
// Called to create the API call.
#NonNull #MainThread
protected abstract LiveData<ApiResponse<RequestType>> createCall();
// Called when the fetch fails. The child class may want to reset components
// like rate limiter.
#MainThread
protected void onFetchFailed() {
}
// returns a LiveData that represents the resource
public final LiveData<Resource<ResultType>> getAsLiveData() {
return result;
}
}
I'm a bit confused here about the use of threads.
Why is #MainThread applied here for networkIO?
Also, for saving into the db, #WorkerThread is applied, whereas #MainThread for retrieving results.
Is it bad practise to use a worker thread by default for NetworkIO and local db interaction?
I'm also checking out the following demo (GithubBrowserSample): https://github.com/googlesamples/android-architecture-components
This confuses me from a threading point of view.
The demo uses executors framework, and defines a fixed pool with 3 threads for networkIO, however in the demo only a worker task is defined for one call, i.e. the FetchNextSearchPageTask. All other network requests seem to be executed on the main thread.
Can someone clarify the rationale?
It seems you have a few misconceptions.
Generally it is never OK to call network from the Main (UI) thread but unless you have a lot of data it might be OK to fetch data from DB in the Main thread. And this is what Google example does.
1.
The demo uses executors framework, and defines a fixed pool with 3 threads for networkIO, however in the demo only a worker task is defined for one call, i.e. the FetchNextSearchPageTask.
First of all, since Java 8 you can create simple implementation of some interfaces (so called "functional interfaces") using lambda syntax. This is what happens in the NetworkBoundResource:
appExecutors.diskIO().execute(() -> {
saveCallResult(processResponse(response));
appExecutors.mainThread().execute(() ->
// we specially request a new live data,
// otherwise we will get immediately last cached value,
// which may not be updated with latest results received from network.
result.addSource(loadFromDb(),
newData -> result.setValue(Resource.success(newData)))
);
});
at first task (processResponse and saveCallResult) is scheduled on a thread provided by the diskIO Executor and then from that thread the rest of the work is scheduled back to the Main thread.
2.
Why is #MainThread applied here for networkIO?
and
All other network requests seem to be executed on the main thread.
This is not so. Only result wrapper i.e. LiveData<ApiResponse<RequestType>> is created on the main thread. The network request is done on a different thread. This is not easy to see because Retrofit library is used to do all the network-related heavy lifting and it nicely hides such implementation details. Still, if you look at the LiveDataCallAdapter that wraps Retrofit into a LiveData, you can see that Call.enqueue is used which is actually an asynchronous call (scheduled internally by Retrofit).
Actually if not for "pagination" feature, the example would not need networkIO Executor at all. "Pagination" is a complicated feature and thus it is implemented using explicit FetchNextSearchPageTask and this is a place where I think Google example is done not very well: FetchNextSearchPageTask doesn't re-use request parsing logic (i.e. processResponse) from RepoRepository but just assumes that it is trivial (which it is now, but who knows about the future...). Also there is no scheduling of the merging job onto the diskIO Executor which is also inconsistent with the rest of the response processing.

AsyncTask equivalent in java

In android there is the AsyncTask which runs a thread and then i can use the method on post execute to interact with main thread again. is there an equivalent to this in java? i am trying to run a timer on separate thread (doInBackground) and once the time is finished it will then allow me to interact with the main theard to restart a service (onPostExecute will restart service)
I'm not Android developer but I think it could be easily implemented by using a CompletableFuture on Java 8:
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.CompletableFuture;
import javax.swing.SwingUtilities;
public abstract class AsyncTask <Params, Progress, Result> {
protected AsyncTask() {
}
protected abstract void onPreExecute();
protected abstract Result doInBackground(Params... params) ;
protected abstract void onProgressUpdate(Progress... progress) ;
protected abstract void onPostExecute(Result result) ;
final void publishProgress(Progress... values) {
SwingUtilities.invokeLater(() -> this.onProgressUpdate(values) );
}
final AsyncTask<Params, Progress, Result> execute(Params... params) {
// Invoke pre execute
try {
SwingUtilities.invokeAndWait( this::onPreExecute );
} catch (InvocationTargetException|InterruptedException e){
e.printStackTrace();
}
// Invoke doInBackground
CompletableFuture<Result> cf = CompletableFuture.supplyAsync( () -> doInBackground(params) );
// Invoke post execute
cf.thenAccept(this::onPostExecute);
return this;
}
}
Solution Tailored for You
In short, look at java: run a function after a specific number of seconds.
For your purpose, you don't need an AsyncTask. AsyncTask is for running something that needs the time, but you would prefer it didn't (e.g. a complex calculation or fetching data from the internet). It's for getting around the problem that you would need to wait.
What you want to do instead is to introduce a delay, or more precisely you want to schedule some action to happen after a delay. You can use a class like AsyncTask for this as well, but it's an overkill and results in more complicated code. You should instead use a class which is tailored for delayed execution, which is Timer and TimerTask:
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
// your code here
}
},
5000
);
Equivalent of AsyncTask in standard Java
Note that AsyncTask is connected to a UI concept (UI = user interface), because it may only be started from the UI thread. It's not for generally running something asynchronously.
Thus, the best matching equivalent of android's AsyncTask is SwingWorker in Java. Swing is Java's standard UI framework. It has a similar concept as android with a UI thread. In Swing, this thread is called the Event Dispatch Thread. Hence, the design of SwingWorker is also very similar to AsyncTask. Even the doInBackground() method has the same name in both classes.
Asynchronous Execution in General
If your requirement is not related to a UI and you only want to source some time consuming operation out so it executes asynchronously, then you need to look at executors. There is a variety of different ways to use executors for many different purposes, so this would go beyond the scope of this answer. If you are interested in further information, start with Jakob Jenkov's tutorial on ExecutorService.

Where's the elegant place to put Endpoint Builder and AsyncTask methods for the generated Endpoint methods

read Where to place the Asynctask in the Application
and http://android-developers.blogspot.com/2009/05/painless-threading.html
Android Studio will generate Endpoint class and Client Libraries for a POJO class with 5 useful methods (get, insert, list, remove, and update).
Attempting these methods on the UI thread is disallowed to protect latency, so calling these methods has to happen on another thread. Many examples show extending AsyncTask as a solution.
For example, I generate endpoints etc for a class called Doctor, and add this private class inside MainActivity in order to add a new Doctor to the database:
private class insertDoctorTask extends AsyncTask<Doctor, Integer, Long> {
protected Long doInBackground(Doctor... ds) {
long res = 1;
try {
Doctor result = endpoint.insertDoctor(ds[0]).execute();
} catch (IOException e) {
e.printStackTrace();
res = 0;
}
return res;
}
}
I will need the same code in other Activities and I'm reluctant to copy and paste it all over the place. What's an elegant way to make this and its companion Tasks (getDoctorTask, listDoctorTask, removeDoctorTask, updateDoctorTask) available to the Activities so that the code is only in one place? And where's the proper place to initialize the endpoint?
Here are a couple of points:
I would tend to keep AsyncTask as private withing the specific Activity, since it is better to link it to the lifecycle of the Activity.
If you are trying to reuse the code in general from different parts (activities) in your Android application, I believe you should look at writing a Service

In android, how can I separate the data loading into its own thread?

So I'm working on my "hello world" application in android/java, and elected to do a sports app (which is strange...I don't like sports...but whatever). So I set up my layout, allow users to 'drill down', so they can see the layout for Baseball, or MLB, or the Indians. Say a user selects 'Indians' from the MLB view. I update the tabs, potentially the color scheme, background, etc, and load the data for the 'news' and 'players' tabs (the latter of which is unique to team layouts). Unfortunately, api calls can sometimes take relatively long to complete, especially when the free API from ESPN is capped at 1 call per second. I do some significant caching already, but there's no way I can guarantee that I won't be loading both 'news' and 'players' for 'Indians' at the same time, so one of the requests will have to wait a full second to return.
So my solution is to have a data loading thread - the UI says 'get me this data', and does the UI work not contingent on the data being there. The question though is - once the data is returned from the data loader (as each piece comes back), how should it update or notify the UI appropriately? My current thought is:
UI thread:
OnSelectIndians()
{
DataLoadThread.GetIndiansPlayers();
DataLoadThread.GetIndiansNews();
// UI stuff
}
OnPlayersLoaded(Array Players)
{
if (layout == INDIANS_LAYOUT) // Make sure we haven't changed layouts
{
foreach player in Players
tab[PLAYERS].textview.text += player
}
}
But this isn't a problem I've had to deal with before. Is this the right way to go about it? Or is there a better/easier design I can use? I don't particularly like requiring the UI thread to have a 'on data returned' method for every type of data I can request. My other loosely-formed idea is to create a lambda function in the UI code, which is passed to the data loader and executed in the data loading thread, so:
DataLoadThread.Queue(
foreach player in GetIndiansPlayers()
myView.tab[PLAYERS].textview.text += player;
);
But I think this is probably the worse route, as now we have 2 threads interacting with the UI. Any advice?
Edit: Okay I got it working using AsyncTask. Out of the box, it still has the problem listed above that I would have to create a new derived class for every type if data I load (so PlayerLoadTask, NewsLoadTask, StandingsLoadTask, etc etc). I also wanted was to have most of the logic visible during the call, so if I'm looking at the event code I know what its doing. Below is the working implementation - would appreciate any feedback on it, but I'll accept the first answer below just the same.
abstract public class LoadDataHelper {
public LoadDataHelper(DataLoader dl, Object param) {
mDataLoader = dl;
mParam = param;
}
abstract public LinkedList<String> LoadData();
protected DataLoader mDataLoader;
protected Object mParam;
}
abstract public class UpdateUIHelper {
public UpdateUIHelper(MyActivity context) {
mContext = context;
}
abstract public void UpdateUI(LinkedList<String> results);
protected MyActivity mContext;
}
private class LoadDataTask extends AsyncTask<Void, Void, LinkedList<String> > {
private LoadDataHelper mLdh;
private UpdateUIHelper mUih;
LoadDataTask(LoadDataHelper ldh, UpdateUIHelper uih) {
mLdh = ldh;
mUih = uih;
}
#Override
protected LinkedList<String> doInBackground(Void... params) {
return mLdh.LoadData();
}
#Override
protected void onPostExecute(LinkedList<String> results) {
mUih.UpdateUI(results);
}
}
//
// .....
//
LoadDataTask task = new LoadDataTask(new LoadDataHelper(mDataLoader, "football") {
public LinkedList<String> LoadData() {
return mDataLoader.LoadLeaguesFromSport((String)mParam);
}
},
new UpdateUIHelper(this) {
public void UpdateUI(LinkedList<String> results) {
TextView tv = (TextView)findViewById(R.id.tv1);
tv.setText("");
for (String res : results) {
tv.append(res + "\n");
}
}
});
task.execute();
Take a look at:
1) AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
The AsyncTask.onPostExecute will be executed in the UI thread.
I think this is the most common technique to do background processing.
2) runOnUIThread: If you are managing your own worker thread, you can use this in a worker thread to make sure code is run on the UI thread.
Its always better to have UI work in UI thread, and Non-UI work in Non-UI thread, But this became a Law from the arrival of HoneyComb in Android.
2 ways to do it in Android.
1. Use Java thread with Handler..
Create a thread to do the process heavy background task, and then display the data using
Handler...
2. Use AsyncTask<>, which is specially designed for Android, to sync the UI work and Non-UI
work. AsyncTask is also known as painless threading.
This is what AsyncTask was designed to do ,
Here is the tutorial that I learned from.
Here is what you do
Create a class that extends AsyncTask
Implement doInBackground and onPostUpdate methods
In the onPostUpdate method update the ui , you can use runOnUiThread to avoid any issues during ui update
The advantage of this using Async tasks is that you can even update the progress and display a visual indicator to the user , You can as easily cancel the task to stop the loading if required
AsyncTask is essentially a helper that simplifies the use of threads
Your best bet is to use the AsyncTask. I created a similar app that made 25+ calls to a server to download images. Using the AsyncTask will cut that time greatly, and still provide a great user experience. Here is a great tutorial on how to use/setup an AsyncTask:
http://www.peachpit.com/articles/article.aspx?p=1823692&seqNum=3
async task is the solution for you
here is a tutorial

Categories

Resources