意外发生致命信号 16 (SIGSTKFLT)

2023-12-31

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

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

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

然后,我以通常的方式运行我的应用程序(就在设备上)。我所有的坏事就这样开始了。对于 1 和 2 设备来说一切正常。但 3 设备并没有按我的预期工作。 LogCat 向我显示了以下致命错误:

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(代码=-6),线程 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 操作系统层使用 malloc() 调用时。当操作系统无法返回 malloc 失败时,它会生成此类致命信号。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

意外发生致命信号 16 (SIGSTKFLT) 的相关文章

随机推荐