0

In the main activity (MainActivity.java) there are several images functionning as buttons. When pressed, an event is triggered hide the UI (but keeps main activity visible) and then to create and launch an new intent. The problem is that the loading of the new intent/activity seems slow (0.5 to 3 seconds), especially after reinstalling the app on a phone (Xperia 10 II) through Android Studio for debugging. The change in timing also depends on which button is pressed. Because each button brings to a different activity and that the "heavier" activities take longer, I'm thinking that the problem is related to how much is loaded in the activities' onCreate() method. Am I right?

My guess is that I need to seperate in different threads what is loaded from memory and what is created for display. And if that's the case, I don't know how to do it.

I quickly read through this article but it doesn't show how to do what it says: Better performance through threading

I also found this post which, because of the name, I thought was what I was looking for. But the answer doesn't seem to match the problem described in the title: Intent is very slow to launch a new Activity :(

I also tried removing the weights in the xml files as suggested in this post, but without success: Activity loads slow

MainActivity.java

public class MainActivity extends AppCompatActivity {

    // Used to load and save data (e.g.: locked and unlocked in-game items)
    public static DataManager dataManager;

    // Instance of player (e.g.: gear and inventory)
    public static Player player;

    private ActivityResultLauncher <Intent> exampleActivityLauncher;
    private ImageButton buttonExample;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        dataManager = new DataManager(this);

        player = new Player();

        this.exampleActivityLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            uiVisible(View.VISIBLE);
        });

        this.buttonExample = this.findViewById(R.id.example);

        this.initExample();
    }

    @Override
    protected void onResume () {
        super.onResume();
        this.initExample();
    }

    private void initExample () {
        this.buttonExample.setOnClickListener(view -> {
            uiVisible(View.INVISIBLE);
            Intent intent = new Intent(MainActivity.this, ExampleActivity.class);
            exampleActivityLauncher.launch(intent);
        });
    }

    private void uiVisible (int visibility) {
        this.buttonExample.setVisibility(visibility);
    }
}

ExampleActivity.java

public class ExampleActivity extends AppCompatActivity {

    // Exetnds "ArrayAdapter <NamedImageView>"
    private static CategoryAdapter adapterCategory;
    // Extends "ArrayAdapter <ExampleItem>"
    private static ExampleAdapter adapterItems;

    // Two-way grid with additional method "getSelection(int position)"
    // Enable selection between listA, listB and listC
    private static SelectionTwoWayGridView selectorCategory;
    // Enable item selection in chosen list (i.e.: category)
    private static SelectionTwoWayGridView selectorItem;

    private static List <CustomItem> listA;
    private static List <CustomItem> listB;
    private static List <CustomItem> listC;

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.initListA();
        this.initListB();
        this.initListC();

        this.setContentView(R.layout.example_activity);

        adapterItems = new ExampleAdapter(this, R.layout.example_item);
        adapterItems.addAll(listA);
        adapterItems.setList(listA);
        selectorItem = this.findViewById(R.id.selector_item);
        selectorItem.setAdapter(adapterItems);
        selectorItem.setSelection(MainActivity.dataManager.loadA());

        adapterCategory = new CategoryAdapter(this, R.layout.example_item, listCategory);
        selectorCategory = this.findViewById(R.id.selector_category);
        selectorCategory.setAdapter(adapterCategory);

        selectorCategory.setOnItemClickListener((parent, view, position, id) -> {
            currentCategory = listCategory.get(position).getName();
            adapterItems.clear();
            switch (currentCategory) {
                case CATEGORY_A :
                    adapterItems.addAll(listA);
                    adapterItems.setList(listA);
                    selectorItem.setSelection(MainActivity.dataManager.loadA());
                    break;
                case CATEGORY_B :
                    adapterItems.addAll(listB);
                    adapterItems.setList(listB);
                    selectorItem.setSelection(MainActivity.dataManager.loadB());
                    break;
                case CATEGORY_C :
                    adapterItems.addAll(listC);
                    adapterItems.setList(listC);
                    selectorItem.setSelection(MainActivity.dataManager.loadC());
                    break;
            }
            selectorCategory.setSelection(position);
            adapterCategory.notifyDataSetChanged();
            selectorItem.invalidateViews();
        });

        selectorItem.setOnItemClickListener((parent, view, position, id) -> {
            ExampleItem item = ((ExampleItem) parent.getItemAtPosition(position));
            if (! item.isUnlocked()) {
                if (MainActivity.player.getCurrentPoints() >= item.getUnlockAmount()) {
                    Intent intent = new Intent(ExampleActivity.this, ActivityPopUpQuestion.class);
                    intent.putExtra("FROM", NAME);
                    intent.putExtra("position", position);
                    intent.putExtra("image", item.getImage());
                    intent.putExtra("title", "");
                    intent.putExtra("type", ActivityPopUpQuestion.TYPE_UNLOCK);
                    startActivity(intent);
                    // User can choose to unlock or to cancel
                    // Unlock uses the below method "unlockItem(position)"
                }
                else {
                    Toast.makeText(ExampleActivity.this, R.string.toast_not_enough_points_to_unlock, Toast.LENGTH_SHORT).show();
                }
            }
            else {
                switch (currentCategory) {
                    case CATEGORY_A :
                        MainActivity.player.A = position;
                        break;
                    case CATEGORY_B :
                        MainActivity.player.B = position;
                        break;
                    case CATEGORY_C :
                        MainActivity.player.C = position;
                        break;
                }
                selectorItem.setSelection(position);
                adapterItems.notifyDataSetChanged();
                MainActivity.dataManager.saveProgress();
            }
        });
    }

    private void initListA () {
        listA = new ArrayList <> ();
        CustomItem startItem = new CustomItem(this, 0, R.drawable.icon_A_0);
        startItem.unlock();
        listA.add(startItem);
        listA.add(new CustomItem(this, 50, R.drawable.icon_A_1));
        listA.add(new CustomItem(this, 50, R.drawable.icon_A_2));
        listA.add(new CustomItem(this, 50, R.drawable.icon_A_3));
        listA.add(new CustomItem(this, 250, R.drawable.icon_A_4));
        listA.add(new CustomItem(this, 250, R.drawable.icon_A_5));
        listA.add(new CustomItem(this, 250, R.drawable.icon_A_6));
        listA.add(new CustomItem(this, 250, R.drawable.icon_A_7));
        listA.add(new CustomItem(this, 500, R.drawable.icon_A_8));
        listA.add(new CustomItem(this, 500, R.drawable.icon_A_9));
        listA.add(new CustomItem(this, 1000, R.drawable.icon_A_10));
        this.updateListWithUnlocks(listA, MainActivity.dataManager.loadUnlocksA());
    }

    private void initListB () {
        listB = new ArrayList <> ();
        CustomItem startItem = new CustomItem(this, 0, R.drawable.icon_B_0);
        startItem.unlock();
        listB.add(startItem);
        listB.add(new CustomItem(this, 50, R.drawable.icon_B_1));
        listB.add(new CustomItem(this, 50, R.drawable.icon_B_2));
        listB.add(new CustomItem(this, 50, R.drawable.icon_B_3));
        listB.add(new CustomItem(this, 250, R.drawable.icon_B_4));
        listB.add(new CustomItem(this, 250, R.drawable.icon_B_5));
        listB.add(new CustomItem(this, 500, R.drawable.icon_B_6));
        this.updateListWithUnlocks(listB, MainActivity.dataManager.loadUnlocksB());
    }

    private void initListC () {
        listC = new ArrayList <> ();
        CustomItem startItem = new CustomItem(this, 0, R.drawable.icon_C_0);
        startItem.unlock();
        listC.add(startItem);
        listC.add(new CustomItem(this, 50, R.drawable.icon_C_1));
        listC.add(new CustomItem(this, 50, R.drawable.icon_C_2));
        listC.add(new CustomItem(this, 50, R.drawable.icon_C_3));
        listC.add(new CustomItem(this, 50, R.drawable.icon_C_4));
        listC.add(new CustomItem(this, 50, R.drawable.icon_C_5));
        listC.add(new CustomItem(this, 250, R.drawable.icon_C_6));
        listC.add(new CustomItem(this, 250, R.drawable.icon_C_7));
        this.updateListWithUnlocks(listC, MainActivity.dataManager.loadUnlocksC());
    }

    public static void unlockItem (int position) {
        PersonalisationItem item = adapterItems.getList().get(position);
        MainActivity.player.removePoints(item.getUnlockAmount());
        item.unlock();
        selectorItem.invalidateViews();
        MainActivity.dataManager.saveUnlocks();
    }
}

Using the code above, what seems to be slow is the appearance/transition of ExampleActivity after pressing on buttonExample.

  1. Why is the transition really slow right after re-installing the app?

  2. Why is the transition slow at all?

  3. How to make the transition faster?

Calvin M.T.
  • 51
  • 1
  • 8

1 Answers1

0

User "Runnable" or thread for background tasks & update UI data in "runOnUiThread".

Dev4Life
  • 2,328
  • 8
  • 22