我有一个名为table()
的方法,它生成一个包含600行的表。当我在onCreate()
中运行此方法时,即在主UI线程中,我从日志中收到一条消息:
I/Choreographer: Skipped 32 frames! The application may be doing too much work on its main thread."
我发现,为了避免跳过帧,我应该使用AsyncTask
。但是,我不知道如何在后台实现表生成?我无法将table()
方法放在doInBackground(Void... params)
中,因为doInBackground
不适用于UI,但我也不能将此方法放在onPostExecute
中,因为它会给我跳过帧。
在AsyncTask
中实现表格生成的正确方法是什么?
以下是table方法的代码,我在onCreate()
public void table(){
ScrollView scrollView = new ScrollView(this);
HorizontalScrollView horizontalScroll = new HorizontalScrollView(this);
TableLayout tableLayout = new TableLayout(this);
tableLayout.setBackgroundColor(Color.BLACK);
LayoutParams cellsParam = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
cellsParam.setMargins(1, 1, 1, 1);
for(int i = 0; i < 600; i++){
TableRow row = new TableRow(this);
TextView wayTextView = new TextView(this);
wayTextView.setText("text" + i);
wayTextView.setBackgroundColor(Color.WHITE);
wayTextView.setGravity(Gravity.CENTER);
row.addView(wayTextView, cellsParam);
tableLayout.addView(row);
}
horizontalScroll.addView(tableLayout);
scrollView.addView(horizontalScroll);
setContentView(scrollView);
}
答案 0 :(得分:0)
有一种叫做#34; loop unrolling&#34;这对你有所帮助(但不是为了优化而做的,我们在这里做的就是将循环划分为一小块大小的“块”阻止UI线程。)
制作6个任务,每个执行100行:或10个60行任务(无论哪种情况最适合您的应用。)
我现在对此进行了测试,并按预期工作
&#39;静态&#39;从顶部算起的是:0 - &gt; (N-1)
package com.example.mike.myapplication;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
static int count = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int totalCount = 600;
int numTasks = 10;
int division = totalCount / numTasks ;
// where did the other loop
for (int i = 0; i < numTasks ; i++) {
new UpdateRowsTask(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, Integer.valueOf(division));
}
}
public void doLog(String str) {
Log.d("TEST", str);
}
private static class UpdateRowsTask extends AsyncTask<Integer, Void, Void> {
int maxCount ;
MainActivity _activity;
public UpdateRowsTask(MainActivity activity) {
_activity = activity;
}
@Override
protected Void doInBackground(Integer... params) {
maxCount = params[0]; // adjustable
return null;
}
protected void onPostExecute(Void result) {
do {
_activity.doLog("" + count);
count++;
}
while ((count % maxCount) != 0 ) ;
}
}
}
我有&#39; log.d()&#39;作为我的&#34; UI线程&#34;操作,但您可以轻松地添加行。
答案 1 :(得分:0)
在阅读了有关AsyncTask的更多信息后,我得出结论,AsyncTask不适合解决我的问题。因为使用AsyncTask我无法更新table()
中的用户界面并在onPostExecute
中运行{{1}}方法也是错误的,因为这样做,我再次在主线程中再做太多工作将收到跳过的帧。