致命错误信号16(SIGSTKFLT)已意外发生
作者:互联网
今天,我面临一个奇怪的问题.
我在三个设备上安装了我的应用程序
>华硕Transformer Pad Infinity TF700T
>三星I9082 Galaxy Grand Duos
> LG Optimus L7 II Dual p715
首先,我使用所有这些设备在Debug模式下从Eclipse运行了我的应用程序.没关系
然后,我以通常的方式(在设备上)运行我的应用程序.这样,我所有的坏事就开始了.对于1和2台设备都可以.但是3台设备无法正常工作. LogCat向我显示了以下致命错误:
01-14 01:36:47.529: E/dalvikvm(11294): threadid=1: stuck on
threadid=14, giving up 01-14 01:36:47.529: A/libc(11294): Fatal signal
16 (SIGSTKFLT) at 0x00002c1e (code=-6), thread 11315 (AsyncTask #4)
我真的不明白,这是怎么回事,为什么1和2的设备都能正常工作,而第三个设备却不能.
谁能解释我,这个错误是什么意思,如何纠正?
UPD1我不使用NDK调用和任何第三方库.
UPD2导致错误的大代码段是(我在这里包括所有事件都将调用绘制过程并将其停止):
//I included all imports for sure that I don't use nothing instead of standard things
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.WindowManager;
public class MyLiveWallpaper extends WallpaperService {
public static final String CONFIGS = "configs";
private WallpaperEngine we;
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
if(we.myDrawTask!=null){
we.myDrawTask.cancel(false);
}
}
@Override
public Engine onCreateEngine() {
we = new WallpaperEngine();
return we;
}
//DeviceScreenSize is some class where I just incapsulate screen width, height and depth obtained in getScreenSize() method
DeviceScreenSize dss = new DeviceScreenSize(0, 0, 0);
class WallpaperEngine extends Engine implements
OnSharedPreferenceChangeListener {
//Some definitions below
............................
public DrawTask myDrawTask = null;
............................
//Some definitions above
WallpaperEngine() {
..............
doubleTapDetector = new GestureDetector(HDLiveWallpaper.this,
new SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
if (mTouchEvents) {
mLastDrawTime = 0;
if(myDrawTask!=null){
myDrawTask.stopAnimationFlag = true;
}
else{
myDrawTask = new DrawTask(getSurfaceHolder(), mPaint);
myDrawTask.execute();
}
return true;
}
return false;
}
});
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
// Register receiver for media events
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);
filter.addAction(Intent.ACTION_MEDIA_CHECKING);
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_EJECT);
filter.addAction(Intent.ACTION_MEDIA_NOFS);
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
filter.addAction(Intent.ACTION_MEDIA_SHARED);
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
filter.addDataScheme("file");
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED) || action.equals(Intent.ACTION_MEDIA_CHECKING)) {
mStorageReady = true;
setTouchEventsEnabled(true);
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
myDrawTask = new DrawTask(getSurfaceHolder(), mPaint);
myDrawTask.execute();
} else {
mStorageReady = false;
setTouchEventsEnabled(false);
if(myDrawTask!=null) myDrawTask.cancel(false);
}
}
};
registerReceiver(mReceiver, filter);
// Register receiver for screen on events
mScreenOnReciever = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println(Intent.ACTION_SCREEN_ON);
if (mScreenWake) {
mLastDrawTime = 0;
}
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
myDrawTask = new DrawTask(getSurfaceHolder(), mPaint);
myDrawTask.execute();
}
};
registerReceiver(mScreenOnReciever, new IntentFilter(Intent.ACTION_SCREEN_ON));
mScreenOffReciever = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println(Intent.ACTION_SCREEN_OFF);
if (mScreenWake) {
mLastDrawTime = 0;
}
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
}
};
registerReceiver(mScreenOffReciever, new IntentFilter(Intent.ACTION_SCREEN_OFF));
setTouchEventsEnabled(mStorageReady);
}
@Override
public void onDestroy() {
super.onDestroy();
mPrefs.unregisterOnSharedPreferenceChangeListener(this);
unregisterReceiver(mReceiver);
unregisterReceiver(mScreenOnReciever);
unregisterReceiver(mScreenOffReciever);
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
myDrawTask = new DrawTask(getSurfaceHolder(), mPaint);
myDrawTask.execute();
mLastDrawTime = 0;
} else {
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
.....................
if (mBitmap != null) {
mBitmap.recycle();
}
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
myDrawTask = new DrawTask(getSurfaceHolder(), mPaint);
myDrawTask.execute();
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
myDrawTask = new DrawTask(getSurfaceHolder(), mPaint);
myDrawTask.execute();
mLastDrawTime = 0;
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep,
float yStep, int xPixels, int yPixels) {
mXOffset = xOffset;
mYOffset = yOffset;
if(myDrawTask!=null){
myDrawTask.cancel(false);
}
myDrawTask = new DrawTask(getSurfaceHolder(), mPaint);
myDrawTask.execute();
}
@Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
this.doubleTapDetector.onTouchEvent(event);
}
public final Bitmap drawableToBitmap(Drawable drawable) {
int targetWidth = (mScroll) ? mMinWidth : dss.getWidth();
int targetHeight = (mScroll) ? mMinHeight : dss.getHeight();
Bitmap bitmap = Bitmap.createBitmap(targetWidth, targetHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
// Rotate
.....................
// Scale bitmap
.....................
return bitmap;
}
void getScreenSize() {
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
dss.setDeviceScreenParams(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
dss.setDeviceScreenParams((Integer) Display.class.getMethod("getRawWidth").invoke(d), (Integer) Display.class.getMethod("getRawHeight").invoke(d), metrics.densityDpi);
} catch (Exception ignored) {}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
DisplayMetrics realSize = new DisplayMetrics();
Display.class.getMethod("getRealMetrics", DisplayMetrics.class).invoke(d, realSize);
dss.setDeviceScreenParams(realSize.widthPixels, realSize.heightPixels, realSize.densityDpi);
} catch (Exception ignored) {}
}
//
// ************************
// DRAW AND ANIMATION TASK
// ************************
//
public class DrawTask extends AsyncTask<Void, Void, Void> {
private final SurfaceHolder _surfaceHolder;
private Paint myPaint;
boolean CancelFlag = false, stopAnimationFlag = false;
//HANDLERS
private final Handler mDrawHandler = new Handler(){
public void handleMessage(android.os.Message msg) { };
};
//WORKERS
private final Runnable mDrawWorker = new Runnable() {
public void run() {
if (mDuration > 0)
{
drawFrame();
}
}
};
DrawTask(SurfaceHolder holder, Paint paint){
_surfaceHolder = holder;
myPaint = paint;
CancelFlag = false;
}
SurfaceHolder getSurfHolder(){
return _surfaceHolder;
}
Paint getPaint(){
return myPaint;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
drawFrame();
while(!CancelFlag){}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
@Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
CancelFlag = true;
}
void drawFrame() {
final SurfaceHolder holder = _surfaceHolder;
Canvas c = null;
boolean getImage = false;
try {
// Lock the canvas for writing
c = holder.lockCanvas();
// Do we need to get a new image?
if (mBitmap == null) {
getImage = true;
} else if (mDuration > 0 && mLastDrawTime < System.currentTimeMillis() - mDuration) {
getImage = true;
} else if (mLastDrawTime == 0) {
getImage = true;
}
// Get image to draw
if (getImage) {
// Get a list of files
String[] assets_files = null;
try {
assets_files = getApplicationContext().getAssets().list("");
} catch (IOException e) {
e.printStackTrace();
}
List<String> str_list = new ArrayList<String>();
for (int fi = 0; fi < assets_files.length; fi++) {
String ext = BitmapUtil.getExtension(assets_files[fi]);
if (ext != null) {
if (ext.equals("jpg") || ext.equals("jpeg") || ext.equals("png") || ext.equals("gif")) {
str_list.add(assets_files[fi]);
}
}
}
assets_files = str_list.toArray(new String[str_list.size()]);
// Increment counter
int nFiles = assets_files.length;
if (mRandom) {
int i = mIndex;
do {
mIndex = (int) (Math.random() * nFiles);
} while (nFiles > 1 && mIndex == i);
} else {
if (++mIndex >= nFiles) {
mIndex = 0;
}
}
InputStream ims = null;
try {
ims = getAssets().open(assets_files[mIndex]);
} catch (IOException e) {
e.printStackTrace();
}
d = Drawable.createFromStream(ims, null);
// Read file to bitmap
mBitmap=null;
mBitmap = drawableToBitmap(d);
// Save the current time
mLastDrawTime = System.currentTimeMillis();
} else if (mBitmap != null && mBitmap.isRecycled()){
mBitmap=null;
mBitmap = drawableToBitmap(d);
}
} catch (NullPointerException npe) {
holder.unlockCanvasAndPost(c);
return;
} catch (RuntimeException re) {
holder.unlockCanvasAndPost(c);
return;
}
try {
if (c != null) {
int xPos;
int yPos;
if (mScroll) {
xPos = 0 - (int) (mWidth * mXOffset);
yPos = 0 - (int) (mHeight * mYOffset);
} else {
xPos = 0;
yPos = 0;
}
try {
c.drawColor(Color.BLACK);
c.drawBitmap(mBitmap, xPos, yPos, myPaint);
} catch (Throwable t) {}
}
} finally {
if (c != null){
if((mPreviousBitmap==null) || (mPreviousBitmap==mBitmap))
holder.unlockCanvasAndPost(c);
else{
if(mTransition!=0)
startAnimation(mTransition, holder, c);
else
holder.unlockCanvasAndPost(c);
}
mPreviousBitmap=null;
mPreviousBitmap = mBitmap;
}
}
// Reschedule the next redraw
mDrawHandler.removeCallbacks(mDrawWorker);
if (mVisible) {
mDrawHandler.postDelayed(mDrawWorker, 1000 / 2);
}
else{CancelFlag=true;}
}
void startAnimation(int animNumber, SurfaceHolder holder, Canvas canvas)
{
switch(animNumber){
case 1:{
canvas.drawBitmap(mBitmap, 0, 0, myPaint);
int tmpPaintAlpha = myPaint.getAlpha();
myPaint.setAlpha(255);
canvas.drawBitmap(mPreviousBitmap, 0, 0, myPaint);
holder.unlockCanvasAndPost(canvas);
myPaint.setAlpha(tmpPaintAlpha);
int i=224;
while(i>=0){
canvas = holder.lockCanvas();
canvas.drawBitmap(mBitmap, 0, 0, myPaint);
myPaint.setAlpha(i);
canvas.drawBitmap(mPreviousBitmap, 0, 0, myPaint);
holder.unlockCanvasAndPost(canvas);
myPaint.setAlpha(255);
i-=18;
}
mLastDrawTime=System.currentTimeMillis();
break;
}
case 2:{
....................
break;
}
}
}
}
...................
}
...................
}
每当我们陷入DrawTask.drawFrame()方法时,即使没有任何通知(mTransition == 0),每次都会发生错误.结果,我看到了:
(1)正确完成初始图像和下一个图像的第一步;
(2)当需要将第二张图像转换为第三张图像时,我只是在不固定的时间段内看到黑屏,然后再次看到我的初始图像并无限重复上述(2).设置的任何更改都不会更改此行为.
UPD3希望我对此问题的详细描述(UPD1,UPD2)可以帮助找到这种奇怪行为的原因.但是,不幸的是,现在不适合我.
预先感谢!
解决方法:
SIGSTKFLT在设备内存不足(尤其是内存不足)时发生.在底层Linux OS层中使用malloc()调用时.当OS无法在malloc中返回失败时,它将生成这种致命信号.
当处理图像占用大量内存时,请尝试使用一些内存节省技术(例如后期绑定图像解码)来解决低内存设备上的上述问题.
首先,您可以尝试将图像重新调整为屏幕分辨率或更低的尺寸,然后再将其发布到画布上.
标签:fatal-error,android,android-asynctask,signals 来源: https://codeday.me/bug/20191010/1883184.html