Android 如何使用AsyncTask避免跳过帧
我有一个名为Android 如何使用AsyncTask避免跳过帧,android,multithreading,android-asynctask,Android,Multithreading,Android Asynctask,我有一个名为table()的方法,它生成一个包含600行的表。当我在onCreate()中运行此方法时,即在主UI线程中,我从日志中收到一条消息,其中显示: I/Choreographer: Skipped 32 frames! The application may be doing too much work on its main thread." 我发现,为了避免跳过帧,我应该使用AsyncTask。但是,我不知道如何在后台实现表生成?我不能将table()方法放在doInBackg
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()中运行它
公共作废表(){
ScrollView ScrollView=新的ScrollView(此);
HorizontalScrollView horizontalScroll=新的HorizontalScrollView(此);
TableLayout TableLayout=新的TableLayout(本);
tableLayout.setBackgroundColor(颜色:黑色);
LayoutParams cellsParam=新的LayoutParams(
LayoutParams.MATCH_父级,
LayoutParams.MATCH_PARENT);
cellsParam.setMargins(1,1,1,1);
对于(int i=0;i<600;i++){
TableRow row=新的TableRow(本);
TextView wayTextView=新的TextView(此);
wayTextView.setText(“文本”+i);
wayTextView.setBackgroundColor(颜色:白色);
wayTextView.setGravity(重力.中心);
row.addView(wayTextView,cellsParam);
tableLayout.addView(行);
}
水平滚动。添加视图(表格布局);
scrollView.addView(水平滚动);
setContentView(滚动视图);
}
有一种称为“”的做法可以帮助您(但我们这样做不是为了“优化”,而是为了将循环划分为不会阻塞UI线程的“小规模”块。)
创建6个任务,每个任务可以执行100行:,或者10个任务,每个任务执行60行(无论发生什么情况,对您的应用程序最有效)
我现在已经测试过了,它可以正常工作了
顶部的“静态”计数是从0->(N-1)开始计数的
package com.example.mike.myapplication;
导入android.content.Context;
导入android.os.AsyncTask;
导入android.support.v7.app.AppActivity;
导入android.os.Bundle;
导入android.util.Log;
公共类MainActivity扩展了AppCompatActivity{
静态整数计数=0;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
整数总数=600;
int numTasks=10;
int division=totalCount/numTasks;
//另一个环路在哪里
对于(int i=0;i
我将“log.d()”作为我的“UI线程”操作,但您可以轻松地将其用作行的添加。阅读了有关AsyncTask的更多信息后,我得出结论,AsyncTask不适合解决我的问题。因为使用AsyncTask,我无法在doInBackground
中更新UI,在onPostExecute
中运行table()
方法也是错误的,因为这样做,我在主线程中再次做了太多工作,并且会再次收到跳过的帧。因为您有很多行,我想,它们都在滚动视图中,您是否考虑过使用带有适配器的ListView(而不是TableLayout)仅在需要时加载项(这里是行)?不,我需要的正是一个表。我上面写的代码只是一个简单的例子。实际上,我将生成包含更多列的表,并在setText()中放置数据库中的数据。所以,我需要一个表。为什么要创建视图而不是使用XML定义的视图?Kevin Krumwiede,你的意思是我为什么要从代码创建表?1。您将结果类型定义为Void
,但是doInBackground()
方法的类型是ContactsListCursorAdapter
,而它应该是Void
。2.AsyncTasks(因为Donut)使用5个后台线程池,因此无法保证许多AsyncTasks的顺序。编辑:我的错。它已在Honeycom中更改。我不明白此解决方案的意义,因为默认情况下异步任务按顺序运行:@IanNewson“ContactsListCursorAdapter”是因为我抓取了其他人的异步任务并进行编辑才能工作。是的,我清理了executor,意识到我对线程的记忆太久远了。我现在用工作代码更新了它。一旦我对它进行了优化,它就变得更干净、更清晰了。
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);
}
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 ) ;
}
}
}