应用可能在其主线程上做了很多工作

时间:2017-05-12 07:10:15

标签: java android multithreading handler

我有一个数量最多的应用程序,并在textView中显示每个数字。它只是另一个代码的样本。但问题是:当我启动应用程序时,查看时间没有任何内容,然后出现一条消息"应用程序没有响应"。日志说"应用程序可能正在对其主线程进行大量工作"。当我搜索时,我看到主题有很多问题和答案"通过新线程/处理程序更新TextView ..."我尝试了许多例子 - 但没有任何作用。我是编程新手,希望有人能告诉我错误。也许它很容易,但我不知道如何得到它。谢谢你的帮助!以下是示例的代码:

package de.androidnewcomer.animation;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import static de.androidnewcomer.animation.R.id.textView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener,Runnable {
private TextView textView;
private int i;
private Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button button=(Button)findViewById(R.id.button);
    button.setOnClickListener(this);
    handler=new Handler();
}
@Override
public void run() {
    count();
}
@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.button:
            count();
            break;
    }
}
public void count() {
    while (i < 10) {
        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText("" + i);
        handler.postDelayed(this,1000);

    }
}
}

编辑:我更新了count() - 方法并增加了int I但是现在输出只是&#34; 10&#34; ...感谢快速回答!这是现在的方法:

public void count() {
i=0;
while (i < 10) {
    i++;
    TextView textView = (TextView) findViewById(R.id.textView);
    textView.setText("" + i);
    handler.postDelayed(this,1000);

}
}

应用程序必须在TextView中每秒显示一到十个数字。 但是,当我启动应用程序时,它只显示十个。 感谢您的帮助

4 个答案:

答案 0 :(得分:2)

首先,我没有明显增加,因此你有无限循环。纠正它。

其次,不要一次又一次地呼叫findViewById()。现在是时候了。 调用一次并在TextView中初始化onCreate()一次。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button button=(Button)findViewById(R.id.button);
    button.setOnClickListener(this);

    // Like this
    TextView textView = (TextView) findViewById(R.id.textView);

    handler=new Handler();
}

第三,在后台执行像using an Async task这样的长时间运行操作。例如:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

因此,在您的情况下,使用TextView中增加的i值更新onPostExecute()(如果您想一次增加所有内容并更新一次)或onProgressUpdate()(如果您想要有所增加并在两者之间发布进展)

推荐阅读The application may be doing too much work on its main thread

答案 1 :(得分:1)

您不会在代码中增加i变量。因此,虽然(i <10){}是无限循环。

答案 2 :(得分:0)

您没有在代码中增加i的值。你可以这样做:

while (i < 10) {
    TextView textView = (TextView) findViewById(R.id.textView);
    textView.setText("" + i);
    i++;
    handler.postDelayed(this,1000);

}

答案 3 :(得分:-1)

您应该在GUI应用程序的上下文中为长时间运行的操作创建单独的线程。请看一下Android-API

public void onClick(View v) {
new Thread(new Runnable() {
    public void run() {
        // a potentially  time consuming task
        final Bitmap bitmap =
                processBitMap("image.png");
        mImageView.post(new Runnable() {
            public void run() {
                mImageView.setImageBitmap(bitmap);
            }
        });
    }
}).start();

}

重要的是:

  mImageView.post(new Runnable() {
        public void run() {
            mImageView.setImageBitmap(bitmap);
        }
    });

创建了一个新线程,可以让您的UI保持响应并同时完成任务。