我的应用程序显示 "The application may be doing too much work on its main thread.",但我不知道是代码的哪一部分导致的
My app is showing "The application may be doing too much work on its main thread.", and I don't know what part of the code is causing this
嗯,我是 Android 编码的新手,我正在开发一个应用程序来教如何种植一些 plants/flower。我正在使用 SQLite 数据库存储数据,但我通过游标调用 class 中的信息,除此之外我不知道该怎么做,所以我的应用程序真的很慢,我猜想这是游标错误,但我无法解决这个问题。
抱歉我的英语不好,我来自巴西 :D.
package com.lmenegalli.homeplanting;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class FlowersSelectedActivity extends AppCompatActivity {
ListView listViewSelected;
int listCounter=0;
String nomeFlor;
String categoria;
ArrayList<String> listItem;
DataBase dab = new DataBase(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.flores_selected);
final Cursor cursor = dab.alldata();
//String categoriaFlor = cursor.getString(7);
listViewSelected=(ListView)findViewById(R.id.array_full);
final ArrayList<String> arrayListSelected = new ArrayList<>();
Bundle b = getIntent().getExtras();
if (b != null) {
categoria = b.getString("categoria");
final String aux = categoria;
}
// Log.d("Teste categoria", categoria);
//arrayListSelected.add("teste");
//=======================================================================
//Teste do CRUD
/*Flores flores = new Flores();
flores.setId(3);
dab.deleteFlor(flores);*/
Toast.makeText(FlowersSelectedActivity.this, "Count: "+cursor.getCount(), Toast.LENGTH_SHORT).show();
if(cursor.getCount()==0){
Toast.makeText(getApplicationContext(),"NO DATA", Toast.LENGTH_LONG).show();
} else{
while(cursor.moveToNext()){
if(cursor.getString(7).equals(categoria)) {
nomeFlor = cursor.getString(1);
arrayListSelected.add(nomeFlor);
}
}
}
ArrayAdapter arrayAdapterSelected = new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrayListSelected);
listViewSelected.setAdapter(arrayAdapterSelected);
listViewSelected.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intentSelected = new Intent(FlowersSelectedActivity.this, ImageCard.class);
String nomeList =(String) adapterView.getItemAtPosition(i);
//I did this because my data was sorted in database, but in ListView not, so when I clicked in something that was sorted, it always get the information of the first item of the list.
//Log.d("Nome",nomeList);
switch (i) {
default:
cursor.moveToPosition(i);
while(!nomeList.equals(cursor.getString(1))) {
cursor.moveToNext();
// I guess the problem is here, but I don't know what is wrong.
}
if(nomeList.equals(cursor.getString(1))){
String nome = cursor.getString(1);
String descricao = cursor.getString(2);
String nomeCientifico = cursor.getString(3);
String imagem = cursor.getString(4);
String comoPlantar = cursor.getString(5);
String imagemPlantio = cursor.getString(6);
intentSelected.putExtra("nome", nome);
intentSelected.putExtra("descricao", descricao);
intentSelected.putExtra("nomeCientifico", nomeCientifico);
intentSelected.putExtra("imagem", imagem);
intentSelected.putExtra("comoPlantar", comoPlantar);
intentSelected.putExtra("imagemPlantio", imagemPlantio);
intentSelected.putExtra("categoria", categoria);
cursor.close();
}
break;
}
startActivityForResult(intentSelected, 1);
}
});
// Toast.makeText(FlowersSelectedActivity.this, "Salvo com Sucesso", Toast.LENGTH_LONG).show();
//========================================================================
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(categoria);
}
public void voltar(View view){
Intent intentVoltar = new Intent(this, MainActivity.class);
getApplicationContext().startActivity(intentVoltar);
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
int id = item.getItemId();
if(id == R.id.home){
this.finish();
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == ImageCard.RESULT_OK){
if(data.getStringExtra("categoriaa") == categoria){
categoria = data.getStringExtra("categoria");
}
}
if (resultCode == ImageCard.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}
}
编辑:Logcat 根据要求在下方。
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:106)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void android.os.Looper.loop() (Looper.java:164)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6647)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[]) (Method.java:-2)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run() (RuntimeInit.java:438)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:811)
2019-11-04 23:50:34.722 11400-11405/com.lmenegalli.homeplanting I/zygote: Do partial code cache collection, code=5KB, data=29KB
2019-11-04 23:50:34.724 11400-11405/com.lmenegalli.homeplanting I/zygote: After code cache collection, code=5KB, data=29KB
2019-11-04 23:50:34.724 11400-11405/com.lmenegalli.homeplanting I/zygote: Increasing code cache capacity to 128KB
2019-11-04 23:50:34.814 11400-11441/com.lmenegalli.homeplanting D/OpenGLRenderer: HWUI GL Pipeline
2019-11-04 23:50:35.032 11400-11441/com.lmenegalli.homeplanting I/Adreno: QUALCOMM build : bca571b, I47556f00c5
Build Date : 04/30/18
OpenGL ES Shader Compiler Version: EV031.22.00.01
Local Branch :
Remote Branch : quic/LA.BR.1.3.7_rb1.11
Remote Branch : NONE
Reconstruct Branch : NOTHING
2019-11-04 23:50:35.150 11400-11441/com.lmenegalli.homeplanting I/Adreno: PFP: 0x004ff087, ME: 0x004ff065
2019-11-04 23:50:35.164 11400-11441/com.lmenegalli.homeplanting I/zygote: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2019-11-04 23:50:35.165 11400-11441/com.lmenegalli.homeplanting I/OpenGLRenderer: Initialized EGL, version 1.4
2019-11-04 23:50:35.165 11400-11441/com.lmenegalli.homeplanting D/OpenGLRenderer: Swap behavior 2
2019-11-04 23:50:35.409 11400-11441/com.lmenegalli.homeplanting D/vndksupport: Loading /vendor/lib/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace.
2019-11-04 23:50:40.714 11400-11405/com.lmenegalli.homeplanting I/zygote: Do partial code cache collection, code=33KB, data=54KB
2019-11-04 23:50:40.716 11400-11405/com.lmenegalli.homeplanting I/zygote: After code cache collection, code=33KB, data=54KB
2019-11-04 23:50:40.716 11400-11405/com.lmenegalli.homeplanting I/zygote: Increasing code cache capacity to 256KB
2019-11-04 23:50:40.903 11400-11400/com.lmenegalli.homeplanting D/Teste drawable: mipmap/babosa_circle
2019-11-04 23:50:40.903 11400-11400/com.lmenegalli.homeplanting D/Teste drawable 2: mipmap/comoplantarbabosa
2019-11-04 23:50:41.586 11400-11405/com.lmenegalli.homeplanting I/zygote: Do full code cache collection, code=123KB, data=98KB
2019-11-04 23:50:41.587 11400-11405/com.lmenegalli.homeplanting I/zygote: After code cache collection, code=112KB, data=62KB
2019-11-04 23:50:42.412 11400-11400/com.lmenegalli.homeplanting I/Choreographer: Skipped 73 frames! The application may be doing too much work on its main thread.
2019-11-04 23:50:42.460 11400-11405/com.lmenegalli.homeplanting I/zygote: Do partial code cache collection, code=121KB, data=74KB
2019-11-04 23:50:42.466 11400-11405/com.lmenegalli.homeplanting I/zygote: After code cache collection, code=121KB, data=74KB
2019-11-04 23:50:42.466 11400-11405/com.lmenegalli.homeplanting I/zygote: Increasing code cache capacity to 512KB
2019-11-04 23:50:52.672 11400-11441/com.lmenegalli.homeplanting D/OpenGLRenderer: endAllActiveAnimators on 0x86c71480 (RippleDrawable) with handle 0x884de8b0
I/Choreographer: Skipped 73 frames! The application may be doing too much work on its main thread.
以上消息基本上是在 Android 的 MainThread/UI 线程超载时出现的。
原因可能是由于复杂的非UI工作、繁重的动画等
要检查是哪个部分导致的,您可以检查 CPU Activity 而 运行 您的应用。
检查这个强official link
官方视频教程Android Performance
如果有帮助就投票
谢谢。快乐编码。
问题从这一行开始:
final Cursor cursor = dab.alldata();
您直接从 MainThread 访问数据库。在 android 中,MainThread 应该仅用于布局更改和 android 框架内容。您总是需要访问数据库或网络服务器之类的东西,您需要在不同的线程中而不是在 MainThread 中进行访问。您可以开始检查 android 中的 AssyncTasks,您会发现解决方案是在不同的线程中访问这些类型的数据。
希望对您有所帮助!
android 应用在 Android OS 主线程上运行。当您在主线程上进行大量处理时会出现此警告。主要是因为从数据库加载数据。所以在你的情况下
final Cursor cursor = dab.alldata();
if(cursor.getCount()==0){
Toast.makeText(getApplicationContext(),"NO DATA", Toast.LENGTH_LONG).show();
} else{
while(cursor.moveToNext()){
if(cursor.getString(7).equals(categoria)) {
nomeFlor = cursor.getString(1);
arrayListSelected.add(nomeFlor);
}
}
}
上面的代码或任何其他你从数据库中获取数据或存储数据的地方,这应该在 AsyncTask
中完成。希望能解决你的问题。
AsyncTask
将在后台进行处理并将结果发送到主线程,因此您可以对数据做任何您想做的事情。
P.S 不要尝试从 AsyncTask doInBackground
方法更新 UI/Adaptor。
嗯,我是 Android 编码的新手,我正在开发一个应用程序来教如何种植一些 plants/flower。我正在使用 SQLite 数据库存储数据,但我通过游标调用 class 中的信息,除此之外我不知道该怎么做,所以我的应用程序真的很慢,我猜想这是游标错误,但我无法解决这个问题。 抱歉我的英语不好,我来自巴西 :D.
package com.lmenegalli.homeplanting;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class FlowersSelectedActivity extends AppCompatActivity {
ListView listViewSelected;
int listCounter=0;
String nomeFlor;
String categoria;
ArrayList<String> listItem;
DataBase dab = new DataBase(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.flores_selected);
final Cursor cursor = dab.alldata();
//String categoriaFlor = cursor.getString(7);
listViewSelected=(ListView)findViewById(R.id.array_full);
final ArrayList<String> arrayListSelected = new ArrayList<>();
Bundle b = getIntent().getExtras();
if (b != null) {
categoria = b.getString("categoria");
final String aux = categoria;
}
// Log.d("Teste categoria", categoria);
//arrayListSelected.add("teste");
//=======================================================================
//Teste do CRUD
/*Flores flores = new Flores();
flores.setId(3);
dab.deleteFlor(flores);*/
Toast.makeText(FlowersSelectedActivity.this, "Count: "+cursor.getCount(), Toast.LENGTH_SHORT).show();
if(cursor.getCount()==0){
Toast.makeText(getApplicationContext(),"NO DATA", Toast.LENGTH_LONG).show();
} else{
while(cursor.moveToNext()){
if(cursor.getString(7).equals(categoria)) {
nomeFlor = cursor.getString(1);
arrayListSelected.add(nomeFlor);
}
}
}
ArrayAdapter arrayAdapterSelected = new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrayListSelected);
listViewSelected.setAdapter(arrayAdapterSelected);
listViewSelected.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intentSelected = new Intent(FlowersSelectedActivity.this, ImageCard.class);
String nomeList =(String) adapterView.getItemAtPosition(i);
//I did this because my data was sorted in database, but in ListView not, so when I clicked in something that was sorted, it always get the information of the first item of the list.
//Log.d("Nome",nomeList);
switch (i) {
default:
cursor.moveToPosition(i);
while(!nomeList.equals(cursor.getString(1))) {
cursor.moveToNext();
// I guess the problem is here, but I don't know what is wrong.
}
if(nomeList.equals(cursor.getString(1))){
String nome = cursor.getString(1);
String descricao = cursor.getString(2);
String nomeCientifico = cursor.getString(3);
String imagem = cursor.getString(4);
String comoPlantar = cursor.getString(5);
String imagemPlantio = cursor.getString(6);
intentSelected.putExtra("nome", nome);
intentSelected.putExtra("descricao", descricao);
intentSelected.putExtra("nomeCientifico", nomeCientifico);
intentSelected.putExtra("imagem", imagem);
intentSelected.putExtra("comoPlantar", comoPlantar);
intentSelected.putExtra("imagemPlantio", imagemPlantio);
intentSelected.putExtra("categoria", categoria);
cursor.close();
}
break;
}
startActivityForResult(intentSelected, 1);
}
});
// Toast.makeText(FlowersSelectedActivity.this, "Salvo com Sucesso", Toast.LENGTH_LONG).show();
//========================================================================
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(categoria);
}
public void voltar(View view){
Intent intentVoltar = new Intent(this, MainActivity.class);
getApplicationContext().startActivity(intentVoltar);
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
int id = item.getItemId();
if(id == R.id.home){
this.finish();
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == ImageCard.RESULT_OK){
if(data.getStringExtra("categoriaa") == categoria){
categoria = data.getStringExtra("categoria");
}
}
if (resultCode == ImageCard.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}
}
编辑:Logcat 根据要求在下方。
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:106)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void android.os.Looper.loop() (Looper.java:164)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6647)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[]) (Method.java:-2)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run() (RuntimeInit.java:438)
2019-11-04 23:50:33.867 11400-11400/com.lmenegalli.homeplanting I/zygote: at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:811)
2019-11-04 23:50:34.722 11400-11405/com.lmenegalli.homeplanting I/zygote: Do partial code cache collection, code=5KB, data=29KB
2019-11-04 23:50:34.724 11400-11405/com.lmenegalli.homeplanting I/zygote: After code cache collection, code=5KB, data=29KB
2019-11-04 23:50:34.724 11400-11405/com.lmenegalli.homeplanting I/zygote: Increasing code cache capacity to 128KB
2019-11-04 23:50:34.814 11400-11441/com.lmenegalli.homeplanting D/OpenGLRenderer: HWUI GL Pipeline
2019-11-04 23:50:35.032 11400-11441/com.lmenegalli.homeplanting I/Adreno: QUALCOMM build : bca571b, I47556f00c5
Build Date : 04/30/18
OpenGL ES Shader Compiler Version: EV031.22.00.01
Local Branch :
Remote Branch : quic/LA.BR.1.3.7_rb1.11
Remote Branch : NONE
Reconstruct Branch : NOTHING
2019-11-04 23:50:35.150 11400-11441/com.lmenegalli.homeplanting I/Adreno: PFP: 0x004ff087, ME: 0x004ff065
2019-11-04 23:50:35.164 11400-11441/com.lmenegalli.homeplanting I/zygote: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2019-11-04 23:50:35.165 11400-11441/com.lmenegalli.homeplanting I/OpenGLRenderer: Initialized EGL, version 1.4
2019-11-04 23:50:35.165 11400-11441/com.lmenegalli.homeplanting D/OpenGLRenderer: Swap behavior 2
2019-11-04 23:50:35.409 11400-11441/com.lmenegalli.homeplanting D/vndksupport: Loading /vendor/lib/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace.
2019-11-04 23:50:40.714 11400-11405/com.lmenegalli.homeplanting I/zygote: Do partial code cache collection, code=33KB, data=54KB
2019-11-04 23:50:40.716 11400-11405/com.lmenegalli.homeplanting I/zygote: After code cache collection, code=33KB, data=54KB
2019-11-04 23:50:40.716 11400-11405/com.lmenegalli.homeplanting I/zygote: Increasing code cache capacity to 256KB
2019-11-04 23:50:40.903 11400-11400/com.lmenegalli.homeplanting D/Teste drawable: mipmap/babosa_circle
2019-11-04 23:50:40.903 11400-11400/com.lmenegalli.homeplanting D/Teste drawable 2: mipmap/comoplantarbabosa
2019-11-04 23:50:41.586 11400-11405/com.lmenegalli.homeplanting I/zygote: Do full code cache collection, code=123KB, data=98KB
2019-11-04 23:50:41.587 11400-11405/com.lmenegalli.homeplanting I/zygote: After code cache collection, code=112KB, data=62KB
2019-11-04 23:50:42.412 11400-11400/com.lmenegalli.homeplanting I/Choreographer: Skipped 73 frames! The application may be doing too much work on its main thread.
2019-11-04 23:50:42.460 11400-11405/com.lmenegalli.homeplanting I/zygote: Do partial code cache collection, code=121KB, data=74KB
2019-11-04 23:50:42.466 11400-11405/com.lmenegalli.homeplanting I/zygote: After code cache collection, code=121KB, data=74KB
2019-11-04 23:50:42.466 11400-11405/com.lmenegalli.homeplanting I/zygote: Increasing code cache capacity to 512KB
2019-11-04 23:50:52.672 11400-11441/com.lmenegalli.homeplanting D/OpenGLRenderer: endAllActiveAnimators on 0x86c71480 (RippleDrawable) with handle 0x884de8b0
I/Choreographer: Skipped 73 frames! The application may be doing too much work on its main thread.
以上消息基本上是在 Android 的 MainThread/UI 线程超载时出现的。 原因可能是由于复杂的非UI工作、繁重的动画等
要检查是哪个部分导致的,您可以检查 CPU Activity 而 运行 您的应用。 检查这个强official link
官方视频教程Android Performance
如果有帮助就投票
谢谢。快乐编码。
问题从这一行开始:
final Cursor cursor = dab.alldata();
您直接从 MainThread 访问数据库。在 android 中,MainThread 应该仅用于布局更改和 android 框架内容。您总是需要访问数据库或网络服务器之类的东西,您需要在不同的线程中而不是在 MainThread 中进行访问。您可以开始检查 android 中的 AssyncTasks,您会发现解决方案是在不同的线程中访问这些类型的数据。
希望对您有所帮助!
android 应用在 Android OS 主线程上运行。当您在主线程上进行大量处理时会出现此警告。主要是因为从数据库加载数据。所以在你的情况下
final Cursor cursor = dab.alldata();
if(cursor.getCount()==0){
Toast.makeText(getApplicationContext(),"NO DATA", Toast.LENGTH_LONG).show();
} else{
while(cursor.moveToNext()){
if(cursor.getString(7).equals(categoria)) {
nomeFlor = cursor.getString(1);
arrayListSelected.add(nomeFlor);
}
}
}
上面的代码或任何其他你从数据库中获取数据或存储数据的地方,这应该在 AsyncTask
中完成。希望能解决你的问题。
AsyncTask
将在后台进行处理并将结果发送到主线程,因此您可以对数据做任何您想做的事情。
P.S 不要尝试从 AsyncTask doInBackground
方法更新 UI/Adaptor。