【问题标题】:Android main thread is doing too much workAndroid主线程做的工作太多
【发布时间】:2018-07-29 00:34:09
【问题描述】:

这个程序中的主线程无论出于什么原因都在做太多的工作。我不知道如何在主线程上使用视图。我尝试过使用 AsyncTask,但我不知道应该如何使用它。

Thread thread2 = new Thread(){
            public void run(){
                while(running){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            try{
                                if(red){
                                    buttons[ran].setImageResource(R.drawable.button_red);
                                    buttons[ran].setTag("Red");
                                    Thread.sleep(duration);
                                    if(buttons[ran].getTag().equals("Red")){
                                        buttons[ran].setTag("Black");
                                        buttons[ran].setImageResource(R.drawable.button_null);
                                        lifeLost();
                                        red = false;
                                    }
                                }else if(white){
                                    buttons[ran].setImageResource(R.drawable.button_white);
                                    buttons[ran].setTag("White");
                                    Thread.sleep(duration);
                                    if(buttons[ran].getTag().equals("White")){
                                        buttons[ran].setTag("Black");
                                        buttons[ran].setImageResource(R.drawable.button_null);
                                        lifeLost();
                                        white = false;
                                    }
                                }
                            }catch(Exception e){

                            }
                        }
                    });
                    try {
                        sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        };
        thread2.start();

这个线程正在做任何我可以给它的非 UI 相关的任务。代码本身实际上在这个线程上工作。但是,它仅适用于较新的设备,而较旧的设备似乎会发现该错误而不是忽略它。

@Override
    public void run() {
        random = new Random();
        random2 = new Random();

    try{
        Thread.sleep(1000);
        while(running){
            ran = random.nextInt(9);
            type = random2.nextInt(3);

            if(lives > 0){
                if(type == 0 || type == 2){
                  red = true;
                }else{
                    white = true;
                }

                if(lives == 0){
                        Thread.sleep(1000);
                        Intent overIntent = new Intent(this, OverActivity.class);
                        overIntent.putExtra("point", score);
                        startActivity(overIntent);
                        overridePendingTransition(0, 0);

                }

                if(score == 10){
                    duration -= 50;
                }else if(score == 20){
                    duration -= 50;
                }else if(score == 30){
                    duration -= 50;
                }else if(score == 40){
                    duration -= 50;
                }
            }
        }
    }catch(Exception e){
        e.printStackTrace();
    }
}

【问题讨论】:

  • 您可以简单地将您的代码放在后台任务中,让它为您返回结果。
  • 您正在调用 runOnUiThread。这意味着它实际上在 UI 线程上运行,而 Thread 没有做任何事情。这意味着您在 UI 线程上调用 sleep ,这绝不是一个好主意。取出runOnUIThread,在线程上实际运行,runOnUiThread中只放视图上实际调用函数的代码。
  • @BashorunOlajide 我会试试的,谢谢。
  • @GabeSechan 之前已经尝试过了。没用
  • @Neptune 我不保证这就足够了,但这是必要的。 runOnUIThread 中的任何内容都在 ui 线程上运行。你不能睡在上面。你不能永远在它上面循环。将大块放入 runOnUiThread 的任何形式的代码都将永远无法工作。

标签: android multithreading


【解决方案1】:

runOnUiThread 命令中的所有内容都在 UI 线程上运行(顾名思义),其中包括您对 Thread.sleep(duration) 的调用(从而导致 UI 线程挂起/做太多工作)。作为一个简单的第一步,尝试将其分成几个 runOnUiThread 调用,并将 Thread.sleep(duration) 语句放在它们之间而不是它们之间。

【讨论】:

    【解决方案2】:

    你可以创建一个类

    public class DoCalculationAsyncTask extends AsyncTask<Void, Void, DataType> {
    
    @SuppressLint("StaticFieldLeak")
    private Context mContext;
    
    public DoCalculationAsyncTask(Context context) {
    
    }
    
    
    @Override
    protected Bitmap doInBackground(Void... params) {
    
        try {
    
        } catch (Exception e) {
    
            e.printStackTrace();
    
        } finally {
    
        }
        return something;
    }
    
    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
    
    } }
    

    然后像这样调用类

     try {
                DoCalculationAsyncTask doCalculationAsyncTask = new
                        DoCalculationAsyncTask(value 1, value 2, value 3, ...);
                doCalculationAsyncTask.execute();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
    

    【讨论】:

    • 我很困惑我应该如何在这里实现我的代码。我是否需要上传位图,然后将值分配给按钮?
    • 不!您始终可以以这种方式编写后台代码并返回值。这是一个错字,我没有完全清理位图代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多