Una regressione è stata introdotta in Android 4.3. Il codice utilizzato nelle versioni precedenti di Android ora causa un arresto anomalo nativo che arresta il processo.Native Crash in Android 4.3 quando si chiama Picture.writeToStream()
L'arresto anomalo si verifica quando si disegna un'immagine che è maggiore di 32 kb in una tela che viene registrata da un oggetto Picture
che viene a sua volta scritto in uno streaming tramite writeToStream()
.
Lo schianto si verifica in Skia quando si tenta di cancellare una stringa (che credo sia l'Uri dell'oggetto immagine).
I/DEBUG(122): #00 pc 0001e3bc /system/lib/libc.so (strlen+72)
I/DEBUG(122): #01 pc 000d9858 /system/lib/libskia.so (SkWriter32::writeString(char const*, unsigned int)+256)
I/DEBUG(122): #02 pc 00113d68 /system/lib/libskia.so (SkImageRef_ashmem::flatten(SkFlattenableWriteBuffer&) const+44)
Il seguente programma mostra come riprodurre questo problema. Tutto ciò che serve è un layout con un pulsante che ha il pulsante 'id'.
public class MainActivity extends Activity {
static final String IMAGE_FILE = Environment.getExternalStorageDirectory() + "/test.jpg";
static final String SKIA_FILE = Environment.getExternalStorageDirectory() + "/test.skia";
private static Bitmap loadBitmap(final String filename) {
Bitmap bitmap = null;
FileInputStream is;
try {
is = new FileInputStream(filename);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inInputShareable = true;
options.inPurgeable = true;
bitmap = BitmapFactory.decodeFileDescriptor(is.getFD(), null, options);
is.close();
} catch (final FileNotFoundException e) {
e.printStackTrace();
} catch (final IOException ex) {
ex.printStackTrace();
}
return bitmap;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
final Runnable runnable = new Runnable() {
@Override
public void run() {
// Create a Canvas and begin recording
final Picture picture = new Picture();
final Canvas canvas = picture.beginRecording(1024, 1024);
// De-compress an image from file
final Bitmap bitmap = loadBitmap(IMAGE_FILE);
// If present draw the image to the canvas and end
// recording
if (bitmap != null) {
canvas.drawBitmap(bitmap, new Matrix(), null);
}
picture.endRecording();
// Write out the Picture object to a Skia File.
FileOutputStream os;
try {
os = new FileOutputStream(SKIA_FILE);
picture.writeToStream(os);
os.close();
} catch (final FileNotFoundException e) {
e.printStackTrace();
} catch (final IOException ex) {
ex.printStackTrace();
}
}
};
new Thread(runnable).start();
}
});
}
}
Le due linee di impostazione dei BitmapFactory.Options sono necessari per ottenere il codice appiattimento Skia per scrivere i dati di immagine (Altrimenti immagini vengono emessi).
options.inInputShareable = true;
options.inPurgeable = true;
Sono consapevole che i metodi Immagine writeToStream()
e createFromStream()
sono stati deprecati, ma non mi aspetto questo per introdurre un problema di stabilità.
Ho bisogno di cancellare l'oggetto Immagine come voglio passare dall'applicazione principale a un processo di servizio. Non posso usare la soluzione consigliata nella documentazione che dice a 'disegnare l'immagine in una bitmap' per i seguenti motivi:
- La risoluzione dell'immagine desiderata non è noto al momento della stesura di distanza.
- L'oggetto immagine deve essere ingrandito tramite una matrice dopo il ripristino.
- Il salvataggio in una bitmap ad altissima risoluzione è inefficiente in termini di memoria e tempo di elaborazione.
Qualcuno sa un lavoro che consente alle immagini di essere scritte nello stream senza causare questo arresto?
Segnalato al progetto Skia come numero 1457: https://code.google.com/p/skia/issues/detail?id=1457 – CAB
Questo dovrebbe essere corretto nella versione futura di Android ora come il nucleo del team di Skia ha controllato in una correzione, vedi https://code.google.com/p/android/issues/detail?id=58257 –