Android: RecyclerView 和 SQLite 数据库 OutOfMemeory 错误?
Android: RecyclerView and SQLite Database OutOfMemeory error?
所以我正在制作咖啡烘焙应用程序。我正在使用数据库保存烘焙配置文件,然后使用 RecyclerView 将其列在另一个 activity 中。问题是,我要么遇到 OutOfMemery 错误,要么 logcat 只是在黑屏时不断来回循环并且没有关闭应用程序。这是 activity 我遇到问题的代码:
RoastListActivity:
package com.coffeeroastingtimer.coffeeroastingtimer.Activities;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Build;
import android.os.Bundle;
import com.coffeeroastingtimer.coffeeroastingtimer.Data.DatabaseHandler;
import com.coffeeroastingtimer.coffeeroastingtimer.Model.RoastProfile;
import com.coffeeroastingtimer.coffeeroastingtimer.R;
import com.coffeeroastingtimer.coffeeroastingtimer.UI.RecyclerViewAdapter;
import java.util.ArrayList;
import java.util.List;
public class RoastListActivity extends AppCompatActivity
{
private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;
private List<RoastProfile> roastProfileList;
private List<RoastProfile> listItems;
private DatabaseHandler db;
private AlertDialog.Builder dialogBuilder;
private AlertDialog dialog;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_roast_list);
db = new DatabaseHandler(this);
//db.getRoastProfileCount();
recyclerView = (RecyclerView) findViewById(R.id.recyclerViewID);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
roastProfileList = new ArrayList<>();
listItems = new ArrayList<>();
roastProfileList = db.getAllRoastProfiles();
for (RoastProfile profile : roastProfileList)
{
RoastProfile roastProfile = new RoastProfile();
roastProfile.setName(profile.getName());
roastProfile.setId(profile.getId());
roastProfile.setFirstCrack(profile.getFirstCrack());
roastProfile.setMaillard(profile.getMaillard());
roastProfile.setYellow(profile.getYellow());
roastProfile.setTemp(profile.getTemp());
roastProfile.setEndTime(profile.getEndTime());
roastProfile.setDateAdded(profile.getDateAdded());
listItems.add(roastProfile);
}
recyclerViewAdapter = new RecyclerViewAdapter(this, listItems);
recyclerView.setAdapter(recyclerViewAdapter);
}
}
RecyclerViewAdapter:
package com.coffeeroastingtimer.coffeeroastingtimer.UI;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.coffeeroastingtimer.coffeeroastingtimer.Activities.RoastDetailsActivity;
import com.coffeeroastingtimer.coffeeroastingtimer.Data.DatabaseHandler;
import com.coffeeroastingtimer.coffeeroastingtimer.Model.RoastProfile;
import com.coffeeroastingtimer.coffeeroastingtimer.R;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>
{
private Context context;
private List<RoastProfile> roastProfiles;
private AlertDialog.Builder alertDialogBuilder;
private AlertDialog dialog;
private LayoutInflater inflater;
public RecyclerViewAdapter(Context context, List<RoastProfile> roastProfiles)
{
this.context = context;
this.roastProfiles = roastProfiles;
}
@NonNull
@Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.roast_list_row, parent, false);
return new ViewHolder(view, context);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
{
RoastProfile roastProfile = roastProfiles.get(position);
holder.row_beanName.setText(roastProfile.getName());
holder.row_date.setText(roastProfile.getDateAdded());
}
@Override
public int getItemCount()
{
return roastProfiles.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
public TextView row_beanName;
public TextView row_date;
public Button row_editButton;
public Button row_deleteButton;
public int row_id;
public ViewHolder(@NonNull View view, Context ctx)
{
super(view);
context = ctx;
row_beanName = (TextView) view.findViewById(R.id.row_name);
row_date = (TextView) view.findViewById(R.id.row_dateAdded);
row_editButton = (Button) view.findViewById(R.id.editButton);
row_deleteButton = (Button) view.findViewById(R.id.deleteButton);
view.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int position = getAdapterPosition();
RoastProfile roastProfile = roastProfiles.get(position);
Intent intent = new Intent(context, RoastDetailsActivity.class);
intent.putExtra("name", roastProfile.getName());
intent.putExtra("date", roastProfile.getDateAdded());
intent.putExtra("id", roastProfile.getId());
intent.putExtra("temp", roastProfile.getTemp());
intent.putExtra("end", roastProfile.getEndTime());
intent.putExtra("fc", roastProfile.getFirstCrack());
intent.putExtra("maillard", roastProfile.getMaillard());
intent.putExtra("yellow", roastProfile.getYellow());
context.startActivity(intent);
}
});
}
@Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.editButton:
int position = getAdapterPosition();
RoastProfile roastProfile = roastProfiles.get(position);
editItem(roastProfile);
break;
case R.id.deleteButton:
position = getAdapterPosition();
roastProfile = roastProfiles.get(position);
deleteItem(roastProfile.getId());
break;
}
}
public void deleteItem(final int id)
{
alertDialogBuilder = new AlertDialog.Builder(context);
inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.confirmation_dialog, null);
Button noButton = view.findViewById(R.id.noButton);
Button yesButton = view.findViewById(R.id.yesButton);
alertDialogBuilder.setView(view);
dialog = alertDialogBuilder.create();
dialog.show();
noButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
dialog.dismiss();
}
});
yesButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
DatabaseHandler db = new DatabaseHandler(context);
db.deleteRoastProfile(id);
roastProfiles.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
dialog.dismiss();
}
});
}
public void editItem(final RoastProfile roastProfile)
{
alertDialogBuilder = new AlertDialog.Builder(context);
inflater = LayoutInflater.from(context);
final View view = inflater.inflate(R.layout.popup, null);
final EditText nameEdit = (EditText) view.findViewById(R.id.nameEditID);
final EditText tempEdit = (EditText) view.findViewById(R.id.tempEditID);
final EditText endEdit = (EditText) view.findViewById(R.id.endEditID);
final EditText yellowEdit = (EditText) view.findViewById(R.id.yellowEditID);
final EditText maillardEdit = (EditText) view.findViewById(R.id.maillardEditID);
final EditText fcEdit = (EditText) view.findViewById(R.id.fcEditID);
final TextView title = (TextView) view.findViewById(R.id.editTitleTextID);
title.setText("Edit Roast Profile");
Button saveButton = (Button) view.findViewById(R.id.saveEditsButtonID);
alertDialogBuilder.setView(view);
dialog = alertDialogBuilder.create();
dialog.show();
nameEdit.setText(roastProfile.getName());
tempEdit.setText(roastProfile.getTemp());
endEdit.setText(roastProfile.getEndTime());
yellowEdit.setText(roastProfile.getYellow());
maillardEdit.setText(roastProfile.getMaillard());
fcEdit.setText(roastProfile.getFirstCrack());
saveButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
DatabaseHandler db = new DatabaseHandler(context);
roastProfile.setName(nameEdit.getText().toString());
roastProfile.setTemp(tempEdit.getText().toString());
roastProfile.setEndTime(endEdit.getText().toString());
roastProfile.setYellow(yellowEdit.getText().toString());
roastProfile.setMaillard(maillardEdit.getText().toString());
roastProfile.setFirstCrack(fcEdit.getText().toString());
db.updateRoastProfile(roastProfile);
dialog.dismiss();
}
});
}
}
}
这是数据库处理程序中可能出现问题的地方之一 class:
public List<RoastProfile> getAllRoastProfiles()
{
SQLiteDatabase db = this.getReadableDatabase();
List<RoastProfile> roastProfileList = new ArrayList<>();
Cursor cursor = db.query(Constants.TABLE_NAME, new String[]
{
Constants.KEY_ID, Constants.KEY_BEAN_NAME, Constants.KEY_PREHEAT_TEMP,
Constants.KEY_YELLOW_PHASE, Constants.KEY_MAILLARD_PHASE, Constants.KEY_FIRST_CRACK,
Constants.KEY_END_TIME, Constants.KEY_DATE_ADDED
},
null, null, null, null,
Constants.KEY_DATE_ADDED + " DESC");
if(cursor.moveToFirst())
{
do
{
RoastProfile roastProfile = new RoastProfile();
roastProfile.setId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Constants.KEY_ID))));
roastProfile.setName(cursor.getString(cursor.getColumnIndex(Constants.KEY_BEAN_NAME)));
roastProfile.setTemp(cursor.getString(cursor.getColumnIndex(Constants.KEY_PREHEAT_TEMP)));
roastProfile.setYellow(cursor.getString(cursor.getColumnIndex(Constants.KEY_YELLOW_PHASE)));
roastProfile.setMaillard(cursor.getString(cursor.getColumnIndex(Constants.KEY_MAILLARD_PHASE)));
roastProfile.setFirstCrack(cursor.getString(cursor.getColumnIndex(Constants.KEY_FIRST_CRACK)));
roastProfile.setEndTime(cursor.getString(cursor.getColumnIndex(Constants.KEY_END_TIME)));
LocalDateTime time = Instant.ofEpochMilli(cursor.getLong(cursor.getColumnIndex(Constants.KEY_DATE_ADDED))).atZone(ZoneId.systemDefault()).toLocalDateTime();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
String formattedDate = time.format(dtf);
roastProfile.setDateAdded(formattedDate);
roastProfileList.add(roastProfile);
} while(cursor.moveToFirst());
}
return roastProfileList;
}
无论出于何种原因,它不再显示 OutOfMemory 错误,因此我无法获得 logcat,但这是无限循环的错误:
2020-06-04 11:03:01.834 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/TextToSpeech: Sucessfully bound to com.google.android.tts
2020-06-04 11:03:01.877 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:01.898 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/TextToSpeech: Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
2020-06-04 11:03:01.899 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:01.902 15957-16013/com.coffeeroastingtimer.coffeeroastingtimer I/TextToSpeech: Set up connection to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
2020-06-04 11:03:02.319 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:03.019 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:03.044 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer D/Saved: Saved to DB
2020-06-04 11:03:03.062 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:03.077 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:05.335 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:06.294 15957-15975/com.coffeeroastingtimer.coffeeroastingtimer W/System: A resource failed to call close.
2020-06-04 11:03:06.294 15957-15975/com.coffeeroastingtimer.coffeeroastingtimer W/System: A resource failed to call close.
2020-06-04 11:03:06.295 15957-15975/com.coffeeroastingtimer.coffeeroastingtimer W/MediaPlayer-JNI: MediaPlayer finalized without being released
2020-06-04 11:03:07.758 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 838729(21MB) AllocSpace objects, 0(0B) LOS objects, 44% free, 30MB/54MB, paused 158us total 138.929ms
2020-06-04 11:03:09.840 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 1200544(31MB) AllocSpace objects, 0(0B) LOS objects, 27% free, 63MB/87MB, paused 155us total 248.451ms
2020-06-04 11:03:12.125 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 1685911(45MB) AllocSpace objects, 0(0B) LOS objects, 18% free, 104MB/128MB, paused 158us total 393.266ms
2020-06-04 11:03:14.761 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Waiting for a blocking GC Alloc
2020-06-04 11:03:14.976 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 2709517(64MB) AllocSpace objects, 0(0B) LOS objects, 16% free, 123MB/147MB, paused 240us total 614.552ms
2020-06-04 11:03:14.976 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: WaitForGcToComplete blocked Alloc on HeapTrim for 214.959ms
2020-06-04 11:03:14.976 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:17.523 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Waiting for a blocking GC Alloc
2020-06-04 11:03:18.015 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 2186455(57MB) AllocSpace objects, 0(0B) LOS objects, 15% free, 131MB/155MB, paused 158us total 729.423ms
2020-06-04 11:03:18.016 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: WaitForGcToComplete blocked Alloc on HeapTrim for 492.071ms
2020-06-04 11:03:24.223 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.254 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 403799(9905KB) AllocSpace objects, 0(0B) LOS objects, 6% free, 180MB/192MB, paused 152us total 30.664ms
2020-06-04 11:03:24.300 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.300 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.331 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 374227(9180KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 180MB/192MB, paused 153us total 31.015ms
2020-06-04 11:03:24.373 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.373 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.403 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 344690(8457KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 181MB/192MB, paused 241us total 29.994ms
2020-06-04 11:03:24.442 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.442 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.472 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 315154(7734KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 181MB/192MB, paused 152us total 29.539ms
2020-06-04 11:03:24.510 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.510 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.540 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 295447(7251KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 182MB/192MB, paused 152us total 30.397ms
2020-06-04 11:03:24.574 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.574 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.604 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 275739(6768KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 182MB/192MB, paused 153us total 29.735ms
2020-06-04 11:03:24.636 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.636 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.665 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 256040(6286KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 183MB/192MB, paused 152us total 29.488ms
2020-06-04 11:03:24.695 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.695 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.725 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 236359(5804KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 183MB/192MB, paused 157us total 29.617ms
2020-06-04 11:03:24.758 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.758 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.788 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 216666(5322KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 183MB/192MB, paused 152us total 29.894ms
2020-06-04 11:03:24.813 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.813 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.843 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 196959(4839KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 183MB/192MB, paused 153us total 29.549ms
2020-06-04 11:03:24.865 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.865 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:25.850 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Clamp target GC heap from 208MB to 192MB
2020-06-04 11:03:25.850 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc concurrent copying GC freed 177511(4363KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 184MB/192MB, paused 168us total 984.860ms
2020-06-04 11:03:25.882 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:25.882 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
抱歉,如果发布所有这些不同的代码块有点矫枉过正,我只是觉得信息越多越好。
如有任何帮助,我们将不胜感激!
在 getAllRoastProfiles 函数的 do while 循环中,将退出条件从
更改为
cursor.moveToFirst()
到
cursor.moveToNext()
原因:cursor.moveToFirst()在do while循环条件下,光标停留在第一行,造成无限循环,从而引发OutOfMemory异常。
所以我正在制作咖啡烘焙应用程序。我正在使用数据库保存烘焙配置文件,然后使用 RecyclerView 将其列在另一个 activity 中。问题是,我要么遇到 OutOfMemery 错误,要么 logcat 只是在黑屏时不断来回循环并且没有关闭应用程序。这是 activity 我遇到问题的代码:
RoastListActivity:
package com.coffeeroastingtimer.coffeeroastingtimer.Activities;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Build;
import android.os.Bundle;
import com.coffeeroastingtimer.coffeeroastingtimer.Data.DatabaseHandler;
import com.coffeeroastingtimer.coffeeroastingtimer.Model.RoastProfile;
import com.coffeeroastingtimer.coffeeroastingtimer.R;
import com.coffeeroastingtimer.coffeeroastingtimer.UI.RecyclerViewAdapter;
import java.util.ArrayList;
import java.util.List;
public class RoastListActivity extends AppCompatActivity
{
private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;
private List<RoastProfile> roastProfileList;
private List<RoastProfile> listItems;
private DatabaseHandler db;
private AlertDialog.Builder dialogBuilder;
private AlertDialog dialog;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_roast_list);
db = new DatabaseHandler(this);
//db.getRoastProfileCount();
recyclerView = (RecyclerView) findViewById(R.id.recyclerViewID);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
roastProfileList = new ArrayList<>();
listItems = new ArrayList<>();
roastProfileList = db.getAllRoastProfiles();
for (RoastProfile profile : roastProfileList)
{
RoastProfile roastProfile = new RoastProfile();
roastProfile.setName(profile.getName());
roastProfile.setId(profile.getId());
roastProfile.setFirstCrack(profile.getFirstCrack());
roastProfile.setMaillard(profile.getMaillard());
roastProfile.setYellow(profile.getYellow());
roastProfile.setTemp(profile.getTemp());
roastProfile.setEndTime(profile.getEndTime());
roastProfile.setDateAdded(profile.getDateAdded());
listItems.add(roastProfile);
}
recyclerViewAdapter = new RecyclerViewAdapter(this, listItems);
recyclerView.setAdapter(recyclerViewAdapter);
}
}
RecyclerViewAdapter:
package com.coffeeroastingtimer.coffeeroastingtimer.UI;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.coffeeroastingtimer.coffeeroastingtimer.Activities.RoastDetailsActivity;
import com.coffeeroastingtimer.coffeeroastingtimer.Data.DatabaseHandler;
import com.coffeeroastingtimer.coffeeroastingtimer.Model.RoastProfile;
import com.coffeeroastingtimer.coffeeroastingtimer.R;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>
{
private Context context;
private List<RoastProfile> roastProfiles;
private AlertDialog.Builder alertDialogBuilder;
private AlertDialog dialog;
private LayoutInflater inflater;
public RecyclerViewAdapter(Context context, List<RoastProfile> roastProfiles)
{
this.context = context;
this.roastProfiles = roastProfiles;
}
@NonNull
@Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.roast_list_row, parent, false);
return new ViewHolder(view, context);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
{
RoastProfile roastProfile = roastProfiles.get(position);
holder.row_beanName.setText(roastProfile.getName());
holder.row_date.setText(roastProfile.getDateAdded());
}
@Override
public int getItemCount()
{
return roastProfiles.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
public TextView row_beanName;
public TextView row_date;
public Button row_editButton;
public Button row_deleteButton;
public int row_id;
public ViewHolder(@NonNull View view, Context ctx)
{
super(view);
context = ctx;
row_beanName = (TextView) view.findViewById(R.id.row_name);
row_date = (TextView) view.findViewById(R.id.row_dateAdded);
row_editButton = (Button) view.findViewById(R.id.editButton);
row_deleteButton = (Button) view.findViewById(R.id.deleteButton);
view.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int position = getAdapterPosition();
RoastProfile roastProfile = roastProfiles.get(position);
Intent intent = new Intent(context, RoastDetailsActivity.class);
intent.putExtra("name", roastProfile.getName());
intent.putExtra("date", roastProfile.getDateAdded());
intent.putExtra("id", roastProfile.getId());
intent.putExtra("temp", roastProfile.getTemp());
intent.putExtra("end", roastProfile.getEndTime());
intent.putExtra("fc", roastProfile.getFirstCrack());
intent.putExtra("maillard", roastProfile.getMaillard());
intent.putExtra("yellow", roastProfile.getYellow());
context.startActivity(intent);
}
});
}
@Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.editButton:
int position = getAdapterPosition();
RoastProfile roastProfile = roastProfiles.get(position);
editItem(roastProfile);
break;
case R.id.deleteButton:
position = getAdapterPosition();
roastProfile = roastProfiles.get(position);
deleteItem(roastProfile.getId());
break;
}
}
public void deleteItem(final int id)
{
alertDialogBuilder = new AlertDialog.Builder(context);
inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.confirmation_dialog, null);
Button noButton = view.findViewById(R.id.noButton);
Button yesButton = view.findViewById(R.id.yesButton);
alertDialogBuilder.setView(view);
dialog = alertDialogBuilder.create();
dialog.show();
noButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
dialog.dismiss();
}
});
yesButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
DatabaseHandler db = new DatabaseHandler(context);
db.deleteRoastProfile(id);
roastProfiles.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
dialog.dismiss();
}
});
}
public void editItem(final RoastProfile roastProfile)
{
alertDialogBuilder = new AlertDialog.Builder(context);
inflater = LayoutInflater.from(context);
final View view = inflater.inflate(R.layout.popup, null);
final EditText nameEdit = (EditText) view.findViewById(R.id.nameEditID);
final EditText tempEdit = (EditText) view.findViewById(R.id.tempEditID);
final EditText endEdit = (EditText) view.findViewById(R.id.endEditID);
final EditText yellowEdit = (EditText) view.findViewById(R.id.yellowEditID);
final EditText maillardEdit = (EditText) view.findViewById(R.id.maillardEditID);
final EditText fcEdit = (EditText) view.findViewById(R.id.fcEditID);
final TextView title = (TextView) view.findViewById(R.id.editTitleTextID);
title.setText("Edit Roast Profile");
Button saveButton = (Button) view.findViewById(R.id.saveEditsButtonID);
alertDialogBuilder.setView(view);
dialog = alertDialogBuilder.create();
dialog.show();
nameEdit.setText(roastProfile.getName());
tempEdit.setText(roastProfile.getTemp());
endEdit.setText(roastProfile.getEndTime());
yellowEdit.setText(roastProfile.getYellow());
maillardEdit.setText(roastProfile.getMaillard());
fcEdit.setText(roastProfile.getFirstCrack());
saveButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
DatabaseHandler db = new DatabaseHandler(context);
roastProfile.setName(nameEdit.getText().toString());
roastProfile.setTemp(tempEdit.getText().toString());
roastProfile.setEndTime(endEdit.getText().toString());
roastProfile.setYellow(yellowEdit.getText().toString());
roastProfile.setMaillard(maillardEdit.getText().toString());
roastProfile.setFirstCrack(fcEdit.getText().toString());
db.updateRoastProfile(roastProfile);
dialog.dismiss();
}
});
}
}
}
这是数据库处理程序中可能出现问题的地方之一 class:
public List<RoastProfile> getAllRoastProfiles()
{
SQLiteDatabase db = this.getReadableDatabase();
List<RoastProfile> roastProfileList = new ArrayList<>();
Cursor cursor = db.query(Constants.TABLE_NAME, new String[]
{
Constants.KEY_ID, Constants.KEY_BEAN_NAME, Constants.KEY_PREHEAT_TEMP,
Constants.KEY_YELLOW_PHASE, Constants.KEY_MAILLARD_PHASE, Constants.KEY_FIRST_CRACK,
Constants.KEY_END_TIME, Constants.KEY_DATE_ADDED
},
null, null, null, null,
Constants.KEY_DATE_ADDED + " DESC");
if(cursor.moveToFirst())
{
do
{
RoastProfile roastProfile = new RoastProfile();
roastProfile.setId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Constants.KEY_ID))));
roastProfile.setName(cursor.getString(cursor.getColumnIndex(Constants.KEY_BEAN_NAME)));
roastProfile.setTemp(cursor.getString(cursor.getColumnIndex(Constants.KEY_PREHEAT_TEMP)));
roastProfile.setYellow(cursor.getString(cursor.getColumnIndex(Constants.KEY_YELLOW_PHASE)));
roastProfile.setMaillard(cursor.getString(cursor.getColumnIndex(Constants.KEY_MAILLARD_PHASE)));
roastProfile.setFirstCrack(cursor.getString(cursor.getColumnIndex(Constants.KEY_FIRST_CRACK)));
roastProfile.setEndTime(cursor.getString(cursor.getColumnIndex(Constants.KEY_END_TIME)));
LocalDateTime time = Instant.ofEpochMilli(cursor.getLong(cursor.getColumnIndex(Constants.KEY_DATE_ADDED))).atZone(ZoneId.systemDefault()).toLocalDateTime();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
String formattedDate = time.format(dtf);
roastProfile.setDateAdded(formattedDate);
roastProfileList.add(roastProfile);
} while(cursor.moveToFirst());
}
return roastProfileList;
}
无论出于何种原因,它不再显示 OutOfMemory 错误,因此我无法获得 logcat,但这是无限循环的错误:
2020-06-04 11:03:01.834 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/TextToSpeech: Sucessfully bound to com.google.android.tts
2020-06-04 11:03:01.877 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:01.898 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/TextToSpeech: Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
2020-06-04 11:03:01.899 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:01.902 15957-16013/com.coffeeroastingtimer.coffeeroastingtimer I/TextToSpeech: Set up connection to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
2020-06-04 11:03:02.319 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:03.019 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:03.044 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer D/Saved: Saved to DB
2020-06-04 11:03:03.062 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:03.077 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:05.335 15957-15982/com.coffeeroastingtimer.coffeeroastingtimer D/EGL_emulation: eglMakeCurrent: 0xf068b1c0: ver 2 0 (tinfo 0xc49e7020)
2020-06-04 11:03:06.294 15957-15975/com.coffeeroastingtimer.coffeeroastingtimer W/System: A resource failed to call close.
2020-06-04 11:03:06.294 15957-15975/com.coffeeroastingtimer.coffeeroastingtimer W/System: A resource failed to call close.
2020-06-04 11:03:06.295 15957-15975/com.coffeeroastingtimer.coffeeroastingtimer W/MediaPlayer-JNI: MediaPlayer finalized without being released
2020-06-04 11:03:07.758 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 838729(21MB) AllocSpace objects, 0(0B) LOS objects, 44% free, 30MB/54MB, paused 158us total 138.929ms
2020-06-04 11:03:09.840 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 1200544(31MB) AllocSpace objects, 0(0B) LOS objects, 27% free, 63MB/87MB, paused 155us total 248.451ms
2020-06-04 11:03:12.125 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 1685911(45MB) AllocSpace objects, 0(0B) LOS objects, 18% free, 104MB/128MB, paused 158us total 393.266ms
2020-06-04 11:03:14.761 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Waiting for a blocking GC Alloc
2020-06-04 11:03:14.976 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 2709517(64MB) AllocSpace objects, 0(0B) LOS objects, 16% free, 123MB/147MB, paused 240us total 614.552ms
2020-06-04 11:03:14.976 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: WaitForGcToComplete blocked Alloc on HeapTrim for 214.959ms
2020-06-04 11:03:14.976 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:17.523 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Waiting for a blocking GC Alloc
2020-06-04 11:03:18.015 15957-15973/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Background concurrent copying GC freed 2186455(57MB) AllocSpace objects, 0(0B) LOS objects, 15% free, 131MB/155MB, paused 158us total 729.423ms
2020-06-04 11:03:18.016 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: WaitForGcToComplete blocked Alloc on HeapTrim for 492.071ms
2020-06-04 11:03:24.223 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.254 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 403799(9905KB) AllocSpace objects, 0(0B) LOS objects, 6% free, 180MB/192MB, paused 152us total 30.664ms
2020-06-04 11:03:24.300 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.300 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.331 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 374227(9180KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 180MB/192MB, paused 153us total 31.015ms
2020-06-04 11:03:24.373 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.373 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.403 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 344690(8457KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 181MB/192MB, paused 241us total 29.994ms
2020-06-04 11:03:24.442 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.442 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.472 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 315154(7734KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 181MB/192MB, paused 152us total 29.539ms
2020-06-04 11:03:24.510 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.510 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.540 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 295447(7251KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 182MB/192MB, paused 152us total 30.397ms
2020-06-04 11:03:24.574 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.574 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.604 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 275739(6768KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 182MB/192MB, paused 153us total 29.735ms
2020-06-04 11:03:24.636 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.636 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.665 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 256040(6286KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 183MB/192MB, paused 152us total 29.488ms
2020-06-04 11:03:24.695 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.695 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.725 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 236359(5804KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 183MB/192MB, paused 157us total 29.617ms
2020-06-04 11:03:24.758 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.758 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.788 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 216666(5322KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 183MB/192MB, paused 152us total 29.894ms
2020-06-04 11:03:24.813 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.813 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.843 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc young concurrent copying GC freed 196959(4839KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 183MB/192MB, paused 153us total 29.549ms
2020-06-04 11:03:24.865 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:24.865 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:25.850 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Clamp target GC heap from 208MB to 192MB
2020-06-04 11:03:25.850 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Alloc concurrent copying GC freed 177511(4363KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 184MB/192MB, paused 168us total 984.860ms
2020-06-04 11:03:25.882 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
2020-06-04 11:03:25.882 15957-15957/com.coffeeroastingtimer.coffeeroastingtimer I/eeroastingtime: Starting a blocking GC Alloc
抱歉,如果发布所有这些不同的代码块有点矫枉过正,我只是觉得信息越多越好。
如有任何帮助,我们将不胜感激!
在 getAllRoastProfiles 函数的 do while 循环中,将退出条件从
更改为cursor.moveToFirst()
到
cursor.moveToNext()
原因:cursor.moveToFirst()在do while循环条件下,光标停留在第一行,造成无限循环,从而引发OutOfMemory异常。