启动新意图后活动加载缓慢

Posted

技术标签:

【中文标题】启动新意图后活动加载缓慢【英文标题】:Slow activity load after launching new intent 【发布时间】:2021-10-02 19:24:29 【问题描述】:

在主 Activity (MainActivity.java) 中有几个用作按钮的图像。按下时,触发事件隐藏 UI(但保持主要活动可见),然后创建和启动新意图。问题是新意图/活动的加载似乎很慢(0.5 到 3 秒),尤其是在通过 android Studio 在手机(Xperia 10 II)上重新安装应用程序以进行调试之后。时间的变化还取决于按下哪个按钮。因为每个按钮都会带来不同的活动,并且“较重”的活动需要更长的时间,所以我认为问题与活动的 onCreate() 方法中加载了多少有关。 我说的对吗?

我的猜测是,我需要在不同的线程中分离从内存中加载的内容和为显示而创建的内容。如果是这样的话,我不知道该怎么做。

我快速通读了这篇文章,但没有说明如何做它所说的:Better performance through threading

我还发现了这篇文章,因为它的名字,我认为这就是我要找的东西。但答案似乎与标题中描述的问题不符:Intent is very slow to launch a new Activity :(

我还尝试按照这篇文章中的建议删除 xml 文件中的权重,但没有成功: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();
    

使用上面的代码,在按下buttonExample 后,ExampleActivity 的出现/转换似乎很慢。

    为什么重新安装应用后过渡真的很慢?

    为什么过渡很慢?

    如何让过渡更快?

【问题讨论】:

【参考方案1】:

用户“Runnable”或后台任务线程和更新“runOnUiThread”中的 UI 数据。

【讨论】:

以上是关于启动新意图后活动加载缓慢的主要内容,如果未能解决你的问题,请参考以下文章

包含viewpager的android活动缓慢打开

Ubuntu 19.04:程序启动缓慢

jQuery DataTables - 启动缓慢,开头显示“普通”html 表

解决冷启动电脑后第一次读取Sqlite数据库缓慢的问题

解决冷启动电脑后第一次读取Sqlite数据库缓慢的问题

iphone中Json数据加载缓慢