Search code examples
androidsqliteserviceintentservice

What process is the best way to send on API and save SQLiteDatabase?


I'm new on Android and working an big app which has sending data to API and saving it on SQlite. All of this process is on one class file . But it leaves me on an error. Sometimes the device hanged. other scenario is the data is incomplete . I have read about Intent Service and Services and I want to learn about the two, but I'm wondering how to get all of my data from UI and put it on services. May I know How?


Solution

  • It depends on the nature of the application. If this should happen in response to a user input...you could well use an AsyncTask. Otherwise, a background service could also do the job.

    What you should NEVER do is run a network operation and/or database access on the main UI thread.

    Services can receive data via intents. The way to send these intents depend on the type of service (Started, Bound or both). There are plenty of resources out there you can read...here's one from Android documentation...

    https://developer.android.com/guide/components/services

    An Example of an AsyncTask

    The example below shows an implementation of AsyncTask that fetches a user's details from a network resource...

    public class FetchUserTask extends AsyncTask<String,Void, UserDTO> {
    
        private FetchUserTaskListener listener;
    
        @Override
        protected UserDTO doInBackground(String...params){
    
            if(params == null || params.length == 0)
                return null;
    
            String userID = params[0];
            UserDataProvider provider = new UserDataProvider(userID);
    
            try {
                return provider.get(userID);
            }
            catch(Exception ex){
                //log the error
                return null;
            }
        }
    
    
        @Override
        protected void onPostExecute(UserDTO user){
            if(listener != null)
                listener.onCompleted(user);
        }
    
        public void setListener(FetchUserTaskListener listener){
            this.listener = listener;
        }
    
        public interface FetchUserTaskListener{
            void onCompleted(boolean success);
        }
    } 
    

    How'd you use this AsyncTask?

    For example, in an Activity, you would use it as below...

    public class UserDetailsActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            //instantiate activity...
            super.onCreate(savedInstanceState);
            setContentView(R.layout.whatever_layout);
    
            fetchUser(userId);
        }
    
        private void fetchUser(String userID){
            FetchUserTask task = new FetchUserTask();
            task.setListener(new FetchUserTaskListener<UserDTO>() {
                @Override
                public void onCompleted(UserDTO user) {
                    //CAUTION: make sure the activity hasn't been stopped before
                    //accessing any UI elements and/or context
                }
            }    
    
            task.execute(userID);
        }
    }
    

    Note

    You can (and will need to) make the example(s) above a bit more sophisticated. For example you can have the FetchUserTaskListener's onCompleted method return also an error message if an error occurred.

    You will also need to check whether the activity has been paused or stopped before you access any context-bound data otherwise you might get an ILlegalStateException.