Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to direct onResume() call

I am rewriting my Android app to eliminate direct calls to onResume().

My app currently does most of its work inside onResume() it then posts the display and that is the end of onResume().

@Override
public void onResume() {
    super.onResume();
    // get current date and time,
    //  and determine if daylight savings time is in effect.
    //...600 lines of code
    // output both the chart and report
    //
    image.setImageBitmap(heightChart);
    report.setImageBitmap(reportBitmap);
}

The next step is gathering user input, which tells me what changes to the report the user wishes. (It may be a new location, a new date, or new display style, etc). This is done as follows:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    final int STATION_REQUEST = 1;
    int test = 1;
    switch (item.getItemId()) {
        case R.id.refresh: {
            userDateSet = false;
            onResume();
            return true;
        } // come to the present.

        //...200 lines of code
        default:
            return super.onOptionsItemSelected(item);
    }
}

As the example shows, the output is regenerated by calling onResume() after the new user command is determined. THIS IS BAD PRACTICE, I ALREADY KNOW!! Yet it works well as far as I have determined, I honestly do not understand the problem with it.

My solution in mind is to gather the 600 lines of code into a separate routine and call that instead, both from within onResume() and numerous points within onOptionsItemSelected()

@Override
public void onResume() {
    super.onResume();
    myOnResumeCode();
}

And inside onOptionsItemSelected() do this

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    final int STATION_REQUEST = 1;
    int test = 1;
    switch (item.getItemId()) {
        case R.id.refresh: {
            userDateSet = false;
            myOnResumeCode();
            return true;
        } // come to the present.

    ... // Other statements
}

Is this method acceptable? If not, any suggestions short of "rewrite the whole thing" will be very helpful to me. I have searched extensively for a clean solution but not found one I can understand. Thank You.

like image 471
user1644002 Avatar asked Jun 01 '18 12:06

user1644002


People also ask

What is the use of onResume () callback method?

onResume() is called whenever you navigate back to the activity from a call or something else. You can override the onResume method similarly as onCreate() and perform the task. This may help you understand the lifecycle of and Android app more.

What is onResume () in android?

onPause() , onResume() : Called when the Activity is leaving the foreground and back to the foreground, can be used to release resources or initialize states.

When onPause method is called in Android?

onPause. Called when the Activity is still partially visible, but the user is probably navigating away from your Activity entirely (in which case onStop will be called next). For example, when the user taps the Home button, the system calls onPause and onStop in quick succession on your Activity .

Which method is invoked when the activity is Started?

onStart() When the activity enters the Started state, the system invokes this callback. The onStart() call makes the activity visible to the user, as the app prepares for the activity to enter the foreground and become interactive. For example, this method is where the app initializes the code that maintains the UI.


1 Answers

I honestly do not understand the problem with it.

Your onResume() method implementation is harmless by itself. But the call to it's super method super.onResume(); will let the system think that it is another occurrence of the resume event. It will lead to unnecessary resource usage for refreshing views and similar internal works. So you must avoid explicit calls to life-cycle callback methods under any circumstances.

Is this method acceptable?

The number of lines of code is doesn't make it acceptable or not. It is a question you need to ask yourself. If you think the whole code is to be executed at that event, then you should do it. Otherwise you could save some resources.

If you are doing something like this

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.mnuEnableSomething:
            {
                refreshTheWholeUi();
                return true;
            }
        case R.id.mnuClearList:
            {
                refreshTheWholeUi();
                return true;
            }
    }
}

public void onResume() {
    super.onResume();
    refreshTheWholeUi();
}

Then changing it to this will be worth of it.

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.mnuEnableSomething:
            {
                enableIt();
                return true;
            }
        case R.id.mnuClearList:
            {
                justClearTheList();
                return true;
            }
    }
}

public void onResume() {
    super.onResume();
    refreshTheWholeUi();
}

Now, to the core of the topic

After your reply, I had a closer look at your question and this struck my eyes.

My plan is to move those 600 lines to a separate class file. That will keep them away from damage while I work on the command decoder in the activity source file

Not actually. But you are really close. Forget about every complexities like activity life-cycle, methods, classes so and so and just focus to the very basic level of execution of a computer program.

A program is always executed line by line. It doesn't make any difference how did you arrange the code. Proper structuring of the program into methods, classes etc are for the sake of programmer's convenience. To the system, its always a series of lines. Therefore while performing heavy duties, the UI may became unresponsive as it have to wait until its turn.

Then how it is possible to do work in parallel?

Multi-Threading...!

It isn't that complicated as it sounds like.

You have to locate the most crucial part of your code which uses the resources more and move it to a different thread.

I have illustrated how to do multi-threading here.

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.mnuProceessImageAction:
            {
                //Let user know that a background operation is running
                //with a progressbar or something
                processImage(mImage);
                return true;
            }
    }
}

private void processImage(Object image) {
    new Thread(new Runnable(){
        public void run() {
        //Doing all the heavy duty here.
        //.............................
        //Now you have the result. Use it to update the UI.
        //(UI can be updated only from the UI thread)
        runOnUiThread(new Runnable(){
                public void run() {
                    updateTheUiWithTheImage(proccessedImage);
                }
        });
        }
    }).start();

}

private void updateTheUiWithTheImage(Object image) {
    try {
        //Hide progressbar if you have one
        //Now it wont make the UI to struggle to use it.
    } catch(NullPointerException e) {
        e.printStackTrace;
    }
}

It is the most basic form. Of course there are alternatives(Like AsyncTask). You can find more about it easily online (Try searching "multi threading in Android"). Feel free to ask more.

like image 185
Bertram Gilfoyle Avatar answered Oct 13 '22 06:10

Bertram Gilfoyle