0

First, I have to say I'm kinda new to native Android development. I put the following code inside onCreate in my MainActivity class.

I never used AsyncTask, so I don't know if this is the best practice to do it. Should I create a new AsyncTask-class and load it somehow in the onCreate method? I put it in the MainActivity onCreate method, because of the scope of variables like bp (billing purchase class), pollfish, counting app-launches, etc.

Also I don't know what to return? Because I have multiple results. There are many tutorials how to create an AsyncTask like this and also suggestions to store SharedPreferences there, but I want to know the best practice for it. For example to get values later in my onResume method or similiar operations.

    new AsyncTask<Context, Void, String>()
    {
        @Override
        protected String doInBackground(Context... params)
        {
            Context context = params[0];
            SharedPreferences pref = context.getSharedPreferences("Pref",Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = pref.edit();

            // Count App Launches
            totalCount = pref.getInt("counter", 0);
            totalCount++;
            editor.putInt("counter", totalCount);
            editor.apply();

            // Pollfish ADS
            int pollfishPref = pref.getInt("pollfish", 0);
            Log.d(TAG,"Application launch count: " + totalCount);
            Log.d(TAG,"pollfish count: " + pollfishPref);

            if (!bp.isPurchased(PRODUCT_ID) && (pollfishPref == 0 || (pollfishPref != 0 && pollfishPref <= totalCount)))
            {
                PollFish.ParamsBuilder paramsBuilder = new PollFish.ParamsBuilder("xxx")
                        .releaseMode(false)
                        .customMode(false)
                        .indicatorPosition(Position.MIDDLE_RIGHT)
                        .indicatorPadding(0)
                        .build();
                PollFish.initWith(MainActivity.this, paramsBuilder);
                mTracker.setScreenName("Pollfish Count: " + pollfishPref + " Applaunch Count: " + totalCount);
                mTracker.send(new HitBuilders.ScreenViewBuilder().build());
            }

            Boolean consumed = pref.getBoolean("consumed", Boolean.parseBoolean(null));
            Log.d(TAG,"consumedPref: " + consumed);

            if (!consumed)
            {
                editor.putBoolean("consumed", true);
                editor.apply();
                bp.consumePurchase(PRODUCT_ID);
                Log.d(TAG,"consumed now!");
            }

            return xxx;
        }

        protected void onPostExecute(String result)
        {
            Log.d(TAG, "Preference received in background: " + result);
        };
    }.execute(this);
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
AlexioVay
  • 4,338
  • 2
  • 31
  • 49

2 Answers2

3

Generally, the best practice is for re-use of the AsyncTask and cleaner code by having a separate class. If you are concerned about variable scope, you can pass those into a constructor for your AsyncTask.

class MyAsyncTask extends AsyncTask<Params, Progress, Result> {
    private Object arg1;

    public MyAsyncTask(Object arg1) {
        this.arg1 = arg1;
    }

    @Override 
    public Result doInBackground(Params... params) { }

    @Override
    public void onPostExecute(Result result) { }
}

Of course, update the necessary object types, and use it like so

new MyAsyncTask(arg1).execute();

You may want to update and retrieve values from the SharedPreferences outside of the AsyncTask then pass in those respective values to the constructor as shown.

I don't know what to return? Because I have multiple results.

Sadly, you can only return one type of class. If you are concerned with how to get a result back from the AsyncTask back to where you called it from, then I would recommend callbacks.

Community
  • 1
  • 1
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • So you mean in the MainActivity `onCreate` method I would have for example 3 times this line `new MyAsyncTask(arg1).execute();` for each case like count app launches, initialize ads (pollfish), check consumed products? But wouldn't I create 3 extra threads then? – AlexioVay Jun 22 '16 at 23:14
  • No, only one task. You would have `new MyAsyncTask(MainActivity.this, counts, pollfishPref, consumed).execute()`, I think. – OneCricketeer Jun 22 '16 at 23:16
  • Ahh okay, I'll try that. Still I'm kinda confused about how to implement those callbacks. Also I have to admit that I don't know if my operations should even belong inside an AsyncTask. Because I have much more inside my onCreate method like initializing AdMobs or the FacebookSDK. Should I put it all inside the AsyncTask also? I'd like to know what advanced developers do about that. I mean that they think "I have to put this inside the AsyncTask and that doesent belong there". Any advice of your thoughts about that and best practices regarding this would help me alot! Thank you. – AlexioVay Jun 22 '16 at 23:30
  • I've only used AsyncTasks for HTTP requests and Database access. I wouldn't advice sticking anything into an AsyncTask unless you actually experience a slow-down in your app or get an explicit error (like a NetworkOnMainThread Exception) – OneCricketeer Jun 22 '16 at 23:32
  • I had a massive slow-down that my app didn't start again (`skipped x frames` message in logcat). I mean the first-time start worked, but after pressing the home button and starting the app again there was just a black screen and nothing else happened then. And it was because of those SharedPreferences (or one of them). Could you maybe edit your answer to show me an example storing a SharedPreference using callback? – AlexioVay Jun 22 '16 at 23:41
  • I don't think SharedPreferences caused that. The `apply`method of SharedPreferences is asynchronous on its own, so it definitely doesn't require an AsyncTask – OneCricketeer Jun 23 '16 at 00:51
  • Hmm, but I stripped down my code to find the line that caused this behaviour and after reading an answer at SO that this could be a problem too I fixed it this way. Anyway I appreciate your help and accept your answer, thank you! Still I have problems implementing the callback function. I opened up a new question, because this one is more specific, maybe you could help me there? http://stackoverflow.com/questions/37980774/implent-an-asynctask-callback-function-returning-multiple-values – AlexioVay Jun 23 '16 at 01:46
1

You should separate the async task into a separate class and make it extend AsyncTask. You can pass variables you need to use through the constructor. This is the best practice because it can make the code easier to read and doesn't block the main thread

nilay neeranjun
  • 145
  • 2
  • 14
  • Hey, thank you, I appreciate your help. I have another concern, maybe you could help me there? http://stackoverflow.com/questions/37980774/implent-an-asynctask-callback-function-returning-multiple-values – AlexioVay Jun 23 '16 at 01:47