意外发生了致命信号 16 (SIGSTKFLT) [英] Fatal signal 16 (SIGSTKFLT) has been occured unexpectedly

查看:27
本文介绍了意外发生了致命信号 16 (SIGSTKFLT)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天我遇到了一个奇怪的问题.我在三台设备上安装了我的应用

Today I faced with a strange issue. I installed my application on three devices

  1. 华硕 Transformer Pad Infinity TF700T
  2. 三星 I9082 Galaxy Grand Duos
  3. LG Optimus L7 II 双 p715

首先,我使用所有这些设备在调试模式下从 Eclipse 运行我的应用程序.没关系.

First, I ran my app from Eclipse in the Debug mode with all of these devices. And it's ok.

然后,我以通常的方式运行我的应用程序(就在设备上).就这样,我所有的坏事都开始了.对于 1 和 2 设备都可以.但是 3 设备没有按我预期的那样工作.LogCat 向我展示了以下致命错误:

Then, I ran my app in usual way (right on devices). And in this way all my bad have been started. For 1 and 2 devices all ok. But 3 device didn't work as I expected. The LogCat showed me the following fatal error:

01-14 01:36:47.529:E/dalvikvm(11294):threadid=1:卡住threadid=14,放弃 01-14 01:36:47.529: A/libc(11294): 致命信号16 (SIGSTKFLT) 在 0x00002c1e (code=-6),线程 11315 (AsyncTask #4)

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 台设备都可以正常工作,但第三台却不能.

I really cannot understand, what's going on and why both 1 and 2 devices work properly, but third doesn't.

谁能解释一下,这个错误意味着什么以及如何纠正?

Could anyone explain me, what this error means and how this can be corrected?

UPD1我不使用 NDK 调用和任何第三方库.

UPD1 I do not use NDK calls and any third-party libraries.

UPD2 导致错误的大代码片段是(我在这里包括所有事件调用绘制过程并停止它):

UPD2 The big code snippet that caused an error is(I include here all events invoke the draw process and stop it):

//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).结果我看到:

Here the error occures every time when we fall in the DrawTask.drawFrame() method even without any anymations (mTransition==0). And as the result I see:

(1) 第一步,初始图像和下一个图像正确完成;

(1) First step with initial image and next image is done properly;

(2) 当需要改变第二到第三等图像时,我只是在不固定的时间内看到黑屏,然后我再次看到我的初始图像并无限重复 (2) 中的所有内容.任何设置更改都不会改变此行为.

(2) When it's time to change second to third etc. images, I just see the black screen during not constant period, and then I see again my initial image and repeat all in (2) infinitely. Any changes of settings don't change this behaviour.

UPD3 希望我对这个问题的详细描述(UPD1、UPD2)可以帮助找到这种奇怪行为的原因.但是,不幸的是,现在不适合我.

UPD3 Hope my detailed descriptions(UPD1, UPD2) of this issue can help to find a reason of this strange behaviour. But, unfortunately, not for me now.

提前致谢!

推荐答案

SIGSTKFLT 在设备内存不足时发生,尤其是在底层 linux 操作系统层中使用 malloc() 调用时.当操作系统无法在 malloc 中返回失败时,它会生成此类致命信号.

SIGSTKFLT happens when the device runs out of memory, esp. when using malloc() calls in the underlying linux OS layer. When the OS cannot return a fail in malloc, it generates a fatal signal of this kind.

在处理占用大量内存的图像时,尝试使用一些内存节省技术(如后期绑定图像解码)来解决低内存设备上的上述问题.

Try using some memory saving techniques(like late binding image decoding) to fix the above issues on low memory devices, when dealing with images as they occupy a lot of memory.

首先,您可以尝试将图像调整为屏幕分辨率或更低,然后再将其发布到画布上.

For a start, You can try re-sizing the image to the screen resolution or lower, before posting it to the canvas.

这篇关于意外发生了致命信号 16 (SIGSTKFLT)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆