Ich habe eine Anwendung entwickelt, die den Dream Service von Android als Bildschirmschoner verwendet - er zeigt eine Diashow mit Bildern an. Diese Bilder sind im Binärformat in einer Datenbank untergebracht und dekodiert. Ich weiß, dass dies nicht der beste Weg ist, aber angesichts der besonderen Struktur und des Zwecks dieser Anwendung ist es am realistischsten. Außerdem macht die Klasse keine ständigen Fahrten zur Datenbank oder dekodiert kontinuierlich das Bild - dies geschieht beim Start und schließt dann die Ressourcen.Android/Java - Nicht genügend Arbeitsspeicher Ausnahme mit Dream Service
Mit dem gesagt, nachdem der Bildschirmschoner für eine Weile ausgeführt wurde, erhalte ich gelegentlich eine "Anwendung hat nicht mehr funktioniert" Nachricht, die ich glaube, ist mit einem Speicherfehler verbunden. Ich finde das ein wenig merkwürdig, weil, soweit mir bekannt ist, die Bitmaps nur einmal decodiert werden - wenn der Dienst an Fenster angeschlossen ist. Ich sehe nicht, warum es Probleme mit dem Speicher geben würde, wenn die einzige sich wiederholende Aktion das Laden einer Bitmap in einen ImageView-Container ist, sicherlich nicht etwas, von dem ich glaube, dass es eine große Menge an Ressourcen erfordert. Ich habe meinen Code überprüft und konnte das Problem nicht finden.
Was mache ich falsch? Wie kann ich verhindern, dass diese Fehler auftreten?
public class screenSaver extends DreamService {
XmlPullParser parser;
String storeImages = "";
// creates messages
public Bitmap drawText(Context c, int resource, String text) {
Resources resources = c.getResources();
Bitmap bitmap = BitmapFactory.decodeResource(resources, resource);
android.graphics.Bitmap.Config config = bitmap.getConfig();
if (config == null) {
config = android.graphics.Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(config, true);
Canvas canvas = new Canvas(bitmap);
TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
float scale = resources.getDisplayMetrics().density;
paint.setColor(Color.BLACK);
paint.setTextSize(48 * scale);
int textWidth = canvas.getWidth() - (int) (16 * scale);
StaticLayout textLayout = new StaticLayout(text, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1f, 0f, false);
int textHeight = textLayout.getHeight();
float x = (bitmap.getWidth() - textWidth)/2;
float y = (bitmap.getHeight() - textHeight)/2;
canvas.save();
canvas.translate(x, y);
textLayout.draw(canvas);
canvas.restore();
return bitmap;
}
ArrayList<Bitmap> imageList = new ArrayList<Bitmap>();
int slideCounter = 0;
ImageView slide;
Cursor images;
Cursor corpImages;
final Handler handler = new Handler(Looper.getMainLooper());
private int counter = 0;
private Runnable runnable = new Runnable() {
@Override
public void run() {
slide.setImageBitmap(imageList.get(counter));
if (counter == (imageList.size() - 1)) {
counter = 0;
} else {
counter++;
}
}
};
public screenSaver() {
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
setInteractive(false);
setFullscreen(true);
setContentView(R.layout.screen_saver);
databaseHelper dbHelper = new databaseHelper(this);
Intent testIntent = new Intent(this, lockActivity.class);
testIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(testIntent); // unpin screen so screen saver can load
SQLiteDatabase db = dbHelper.getReadableDatabase();
SharedPreferences preferences = getSharedPreferences("config", MODE_PRIVATE);
final String store = preferences.getString("store", "");
String managerMessageText = "";
String mainMessageText = "";
String districtMessageText = "";
try {
FileInputStream input = new FileInputStream(new File(this.getFilesDir(), "stores.xml"));
parser = Xml.newPullParser();
parser.setInput(input, null);
// begin search for correct 'store' tag
boolean elementsRemain = true;
while (elementsRemain) {
parser.next();
int event = parser.getEventType();
switch (event) {
case XmlPullParser.START_TAG:
String name = parser.getName();
if (name.equals("store")) {
Log.i("Screen Saver", "entering if store");
String number = parser.getAttributeValue(null, "number");
if (number.equals(store)) {
// located corresponding store, beginning parsing to find associate images and messages
boolean withinStore = true;
while (withinStore) {
parser.next();
if (parser.getEventType() == XmlPullParser.START_TAG) {
String tag = parser.getName();
if (tag.equals("images")) {
parser.nextTag();
while (parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("image")) {
if (parser.getAttributeValue(null, "id") != null && (!parser.getAttributeValue(null, "id").equals(""))) {
storeImages += parser.getAttributeValue(null, "id") + ",";
}
parser.nextTag();
if (parser.getEventType() == XmlPullParser.END_TAG) {
parser.nextTag();
}
}
}
parser.next();
if (parser.getEventType() == XmlPullParser.TEXT) {
switch (tag) {
case "message":
managerMessageText += parser.getText();
break;
case "district":
districtMessageText += parser.getText();
break;
case "corporate":
mainMessageText += parser.getText();
break;
default:
break;
}
}
} else if (parser.getEventType() == XmlPullParser.END_TAG && parser.getName().equals("store")) {
withinStore = false;
}
}
parser.next();
}
} else {
}
break;
case XmlPullParser.END_DOCUMENT:
elementsRemain = false;
break;
}
}
} catch (Exception e) {
Log.e("Error reading XML ", " " + e.getMessage());
}
/* LTO images
try {
File managerFile = new File(this.getFilesDir(), store + ".txt");
File universalFile = new File(this.getFilesDir(), "universal.txt");
File districtFile = new File(this.getFilesDir(), "district.txt");
BufferedReader reader = new BufferedReader(new FileReader(managerFile));
managerMessageText = reader.readLine();
reader = new BufferedReader(new FileReader(universalFile));
mainMessageText = reader.readLine();
reader = new BufferedReader(new FileReader(districtFile));
districtMessageText = reader.readLine();
} catch (Exception e) {
Log.e("Error opening file: ", e.getMessage());
}*/
/* images = db.rawQuery("SELECT " + databaseHelper.IMAGE + " FROM " + databaseHelper.TABLE_NAME + " where " + databaseHelper.LTO + " = 1", null);
images.moveToFirst();
while(!images.isAfterLast()) {
imageList.add(BitmapFactory.decodeByteArray(images.getBlob(images.getColumnIndex(databaseHelper.IMAGE)), 0, images.getBlob(images.getColumnIndex(databaseHelper.IMAGE)).length));
images.moveToNext();
}
images.close(); */
if (storeImages.length() > 1) {
storeImages = storeImages.substring(0, storeImages.length() - 1); // remove trailing comma
}
// get all images that are associated with store
corpImages = db.rawQuery("SELECT " + databaseHelper.SLIDE_IMAGE + " FROM " + databaseHelper.SLIDE_TABLE + " WHERE " + databaseHelper.SLIDE_ID + " IN (" + storeImages + ")", null);
corpImages.moveToFirst();
while (!corpImages.isAfterLast()) {
imageList.add(BitmapFactory.decodeByteArray(corpImages.getBlob(corpImages.getColumnIndex(databaseHelper.SLIDE_IMAGE)), 0, corpImages.getBlob(corpImages.getColumnIndex(databaseHelper.SLIDE_IMAGE)).length));
corpImages.moveToNext();
}
corpImages.close();
db.close();
// begin drawing message bitmaps
if (managerMessageText != "") {
imageList.add(drawText(this, R.drawable.message_background, "Manager Message: \n" + managerMessageText));
}
if (mainMessageText != "") {
imageList.add(drawText(this, R.drawable.message_background, "Corporate Message: \n" + mainMessageText));
}
if (districtMessageText != "") {
imageList.add(drawText(this, R.drawable.message_background, "District Manager Message: \n" + districtMessageText));
}
slide = (ImageView) findViewById(R.id.slider);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
updateGUI();
}
}, 0, 8000);
}
;
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
// unpin screen so it can update
Intent testIntent = new Intent(this, lockActivity.class);
testIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(testIntent); // unpin screen so it can update
}
private void updateGUI() {
if (reminder.running || hourlyReminder.running) {
this.finish();
} else {
handler.post(runnable);
}
}
}
Vielen Dank für jede Anleitung.
ich ziemlich sicher bin, das ein Problem mit Bitmap-Laden ist. Lesen Sie [diese] (https://developer.android.com/training/displaying-bitmaps/load-bitmap.html) –