一些 logcat 错误 - 致命异常

Posted

技术标签:

【中文标题】一些 logcat 错误 - 致命异常【英文标题】:some logcat errors - FATAL EXCEPTION 【发布时间】:2016-04-08 13:10:18 【问题描述】:

我正在尝试在 adt 中运行“photor”演示 sdk,但出现以下 logcat 错误和应用程序崩溃!

活动代码:

package com.example.fotorsdkdemo;

import java.io.File;

import com.everimaging.fotorsdk.FotorConstants;
import com.everimaging.fotorsdk.FotorSDKActivity;
import com.everimaging.fotorsdk.FotorSDKVersion;
import com.everimaging.fotorsdk.FotorUtils;
import com.everimaging.fotorsdk.provider.FotorContentProvider;
import com.everimaging.fotorsdk.provider.FotorContentProvider.SessionColumns;
import com.everimaging.fotorsdk.provider.FotorContentProvider.SessionColumns.Session;
import com.everimaging.fotorsdk.utils.BitmapDecodeUtils;
import com.everimaging.fotorsdk.utils.Utils;
import com.everimaging.fotorsdk.engine.FotorHDFilter;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.ImageColumns;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Sample main activity
 * 
 * @description
 * 
 * @author <a href="mailto:zhangjiajun@everimaging.com">John.Zhang</a>
 * @version 1.0
 * @create Apr 12, 2014 3:06:39 PM
 * @update Apr 12, 2014 3:06:39 PM
 */
public class MainActivity extends Activity 

    private static final int ACTION_REQUEST_FEATURE = 2;

    private static final int ACTION_REQUEST_GALLERY = 3;

    public static final String LOG_TAG = "fotorsdk_demo";

    /** Folder name on the sdcard where the images will be saved **/

    private static final String FOLDER_NAME = "FotorSDK";

    /** Edit sample button */
    Button mEditButton;
    /** Call gallery button */
    Button mGalleryButton;
    /** Display image view */
    ImageView mImage;
    /** The path for output file */
    Uri mOutputFilePath;

    /** Image uri for image editor */
    Uri mImageUri;
    /** Display version label for DEBUG */
    private TextView mSDKVersionLabel;

    /** The sample image uri. */
    private Uri mSampleUri;

    private File mGalleryFolder;

    /** session id for the hi-res post processing */
    private String mSessionId;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        Log.i(LOG_TAG, "onCreate");
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mEditButton.setOnClickListener(new View.OnClickListener() 

            @Override
            public void onClick(View v) 
                // if (mImageUri != null) 
                // startFeature(mImageUri);
                // 
                if (mSampleUri != null) 
                    startFeature(mSampleUri);
                
            
        );

        mGalleryButton.setOnClickListener(new View.OnClickListener() 

            @Override
            public void onClick(View v) 
                pickFromGallery();
            
        );

        mGalleryFolder = createFolders();

        // add sample image
        mSampleUri = Uri.parse("file:///android_asset/sample.jpg");
        loadAsync(mSampleUri);

        if (BuildConfig.DEBUG) 
            mSDKVersionLabel.setText("V" + FotorSDKVersion.FOTOR_SDK_VERSION);
        

    

    /**
     * Start the activity to pick an image from the user gallery
     */
    private void pickFromGallery() 
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");

        Intent chooser = Intent.createChooser(intent, "Choose a Picture");
        startActivityForResult(chooser, ACTION_REQUEST_GALLERY);

    

    @Override
    protected void onResume() 
        Log.i(LOG_TAG, "onResume");
        super.onResume();

        if (getIntent() != null) 
            handleIntent(getIntent());
            setIntent(new Intent());
        
    

    /**
     * Handle the incoming @link Intent
     */
    private void handleIntent(Intent intent) 

        String action = intent.getAction();

        if (null != action) 

            if (Intent.ACTION_SEND.equals(action)) 

                Bundle extras = intent.getExtras();
                if (extras != null && extras.containsKey(Intent.EXTRA_STREAM)) 
                    Uri uri = (Uri) extras.get(Intent.EXTRA_STREAM);
                    loadAsync(uri);
                
             else if (Intent.ACTION_VIEW.equals(action)) 
                Uri data = intent.getData();
                Log.d(LOG_TAG, "data: " + data);
                loadAsync(data);
            
        
    

    /**
     * Load the incoming Image
     * 
     * @param uri
     */
    private void loadAsync(final Uri uri) 
        Log.i(LOG_TAG, "loadAsync: " + uri);

        Drawable toRecycle = mImage.getDrawable();
        if (toRecycle != null && toRecycle instanceof BitmapDrawable) 
            if (((BitmapDrawable) mImage.getDrawable()).getBitmap() != null)
                ((BitmapDrawable) mImage.getDrawable()).getBitmap().recycle();
        
        mImage.setImageDrawable(null);
        mImageUri = null;

        DownloadAsync task = new DownloadAsync();
        task.execute(uri);
    

    @Override
    protected void onDestroy() 
        Log.i(LOG_TAG, "onDestroy");
        super.onDestroy();
        mOutputFilePath = null;
    

    @Override
    public void onContentChanged() 
        super.onContentChanged();

        System.out.println("context:" + this.getPackageName());

        mEditButton = (Button) findViewById(R.id.button2);

        mGalleryButton = (Button) findViewById(R.id.button_gallery);

        mImage = (ImageView) findViewById(R.id.image);

        mSDKVersionLabel = (TextView) findViewById(R.id.fotor_sdk_version_label);

    

    @Override
    /**
     * This method is called when feather has completed ( ie. user clicked on "done" or just exit the activity without saving ). <br />
     * If user clicked the "done" button you'll receive RESULT_OK as resultCode, RESULT_CANCELED otherwise.
     * 
     * @param requestCode
     *  - it is the code passed with startActivityForResult
     * @param resultCode
     *  - result code of the activity launched ( it can be RESULT_OK or RESULT_CANCELED )
     * @param data
     *  - the result data
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
        if (resultCode == RESULT_OK) 
            switch (requestCode) 
            case ACTION_REQUEST_FEATURE: 

                Uri uri = data.getData();
                Bitmap bitmap = BitmapDecodeUtils.decode(this, uri, 0, 0);
                setImageURI(uri, bitmap);
                new ProcessHDTask(this).execute();
            
                break;
            case ACTION_REQUEST_GALLERY: 
                Uri uri = data.getData();
                loadAsync(uri);
                startFeature(uri);
            
                break;
            

         else if (resultCode == RESULT_CANCELED) 
            switch (requestCode) 
            case ACTION_REQUEST_FEATURE:
                if (mSessionId != null)
                    deleteSession(mSessionId);
                break;
            
        
    

    private String onSaveCompletion() 

        Uri sessionUri = SessionColumns.getContentUri(this, mSessionId);

        Cursor cursor = getContentResolver().query(sessionUri, null, null,
                null, null);

        Session session = Session.create(cursor);

        if (session != null) 
            FotorHDFilter fotorHDFilter = new FotorHDFilter(this, session);

            fotorHDFilter.loadImage();

            fotorHDFilter.executeFilter();

            String dstPath = Utils.getSDPath() + "/testOriginal.jpg";

            fotorHDFilter.save(dstPath);

            fotorHDFilter.dispose();
            deleteSession(mSessionId);

            return dstPath;
        
        return null;

    

    class ProcessHDTask extends AsyncTask<Void, Void, String> 
        private ProgressDialog mDialog;

        private Context mContext;

        public ProcessHDTask(Context context) 
            this.mContext = context;
        

        @Override
        protected void onPreExecute() 
            mDialog = ProgressDialog.show(mContext, "Process HD",
                    "Please wait...");
        

        @Override
        protected String doInBackground(Void... params) 
            return onSaveCompletion();
        

        @Override
        protected void onPostExecute(String result) 
            mDialog.dismiss();

            String msg = "Process Error";
            if (result != null) 
                msg = result;
            

            Toast.makeText(mContext, msg, Toast.LENGTH_LONG).show();
        

    

    /**
     * Delete the session and all it's actions. We do not need it anymore.<br />
     * Note that this is optional. All old sessions are automatically removed in
     * Feather.
     * 
     * @param session_id
     */
    private void deleteSession(final String session_id) 
        Uri uri = FotorContentProvider.SessionColumns.getContentUri(this,
                session_id);
        int count = getContentResolver().delete(uri, null, null);
        System.out.println("delete session count:" + count);
    

    /**
     * Given an Uri load the bitmap into the current ImageView and resize it to
     * fit the image container size
     * 
     * @param uri
     */
    @SuppressWarnings("deprecation")
    private boolean setImageURI(final Uri uri, final Bitmap bitmap) 

        Log.d(LOG_TAG,
                "image size: " + bitmap.getWidth() + "x" + bitmap.getHeight());
        mImage.setImageBitmap(bitmap);
        mImage.setBackgroundDrawable(null);

        mEditButton.setEnabled(true);
        mImageUri = uri;
        return true;
    

    /**
     * We need to notify the MediaScanner when a new file is created. In this
     * way all the gallery applications will be notified too.
     * 
     * @param file
     */
    private void updateMedia(String filepath) 
        Log.i(LOG_TAG, "updateMedia: " + filepath);
        MediaScannerConnection.scanFile(getApplicationContext(),
                new String[]  filepath , null, null);
    

    /**
     * Pick a random image from the user gallery
     * 
     * @return
     */
    @SuppressWarnings("unused")
    private Uri pickRandomImage() 
        Cursor c = getContentResolver().query(
                Images.Media.EXTERNAL_CONTENT_URI,
                new String[]  ImageColumns._ID, ImageColumns.DATA ,
                ImageColumns.SIZE + ">?", new String[]  "90000" , null);
        Uri uri = null;

        if (c != null) 
            int total = c.getCount();
            int position = (int) (Math.random() * total);
            Log.d(LOG_TAG, "pickRandomImage. total images: " + total
                    + ", position: " + position);
            if (total > 0) 
                if (c.moveToPosition(position)) 
                    String data = c.getString(c
                            .getColumnIndex(Images.ImageColumns.DATA));
                    long id = c.getLong(c
                            .getColumnIndex(Images.ImageColumns._ID));

                    uri = Uri.parse(data);

                    Log.d(LOG_TAG, uri.toString());
                
            
            c.close();
        
        return uri;
    

    /**
     * Return a new image file. Name is based on the current time. Parent folder
     * will be the one created with createFolders
     * 
     * @return
     * @see #createFolders()
     */
    private File generateOutputFileName() 
        if (mGalleryFolder != null) 
            if (mGalleryFolder.exists()) 
                File file = new File(mGalleryFolder, "Fotor_"
                        + System.currentTimeMillis() + ".jpg");
                return file;
            
        
        return null;
    

    /**
     * Once you've chosen an image you can start the feather activity
     * 
     * @param uri
     */
    private void startFeature(Uri uri) 

        Log.d(LOG_TAG, "uri: " + uri);

        // first check the external storage availability
        if (!isExternalStorageAvilable()) 
            new AlertDialog.Builder(this)
                    .setTitle(android.R.string.dialog_alert_title)
                    .setMessage("External Storage is not avilable").show();
            return;
        

        // create a temporary file where to store the resulting image
        File file = generateOutputFileName();

        if (null != file) 
            mOutputFilePath = Uri.fromFile(file);
         else 
            new AlertDialog.Builder(this)
                    .setTitle(android.R.string.dialog_alert_title)
                    .setMessage("Failed to create a new File").show();
            return;
        

        // Create the intent needed to start feather
        Intent newIntent = new Intent(this, FotorSDKActivity.class);

        // === INPUT IMAGE URI ===
        // Set the source image uri
        newIntent.setData(uri);

        // === OUTPUT ====
        // Optional
        // Pass the uri of the destination image file.
        // This will be the same uri you will receive in the onActivityResult

        System.out.println("mOutputFilePath->:" + mOutputFilePath);

        // newIntent.putExtra(FotorConstants.EXTRA_OUTPUT_PATH,
        // mOutputFilePath);

        // === OUTPUT QUALITY ===
        // Optional
        newIntent.putExtra(FotorConstants.EXTRA_OUTPUT_QUALITY, 90);

        // === MAX SIZE ===
        // Optional
        // you can pass the maximum allowed image size (for the preview),
        // otherwise feather will determine
        // the max size based on the device informations.
        // This will not affect the hi-res image size.
        // Here we're passing the current display size as max image size because
        // after
        // the execution of Aviary we're saving the HI-RES image so we don't
        // need a big
        // image for the preview
        final DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);

        int max_size = Math.max(metrics.widthPixels, metrics.heightPixels);

        max_size = (int) ((float) max_size / 1.4f);

        newIntent.putExtra(FotorConstants.EXTRA_MAX_PREVIEW_SIZE, max_size);

        mSessionId = FotorUtils.generateSessionId(this);

        getContentResolver().delete(
                SessionColumns.getContentUri(this, mSessionId), null, null);

        Log.d(LOG_TAG,
                "session: " + mSessionId + ", size: " + mSessionId.length());

        newIntent.putExtra(FotorConstants.EXTRA_FOTOR_SESSION_ID, mSessionId);

        // // === FEATURE LIST ===

        // newIntent.putExtra(FotorConstants.EXTRA_FEATURE_LIST, new String[] 
        // FotorFeaturesFactory.FeatureType.FX_EFFECTS.name(),
        // FotorFeaturesFactory.FeatureType.BORDER.name() );

        // Whether hide confirm dialog when user not saved the was changed
        // bitmap
        // This default value will show
        // newIntent.putExtra(FotorConstants.EXTRA_HIDE_DISCARD_ALERT, false);

        // Whether input image no changes,were made to the image.
        // newIntent.putExtra(FotorConstants.EXTRA_SAVE_ON_NO_CHANGES, true);

        // start feather
        startActivityForResult(newIntent, ACTION_REQUEST_FEATURE);
    

    /**
     * Check the external storage status
     * 
     * @return
     */
    private boolean isExternalStorageAvilable() 
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) 
            return true;
        
        return false;
    

    /**
     * Try to create the required folder on the sdcard where images will be
     * saved to.
     * 
     * @return
     */
    private File createFolders() 

        File baseDir;

        if (android.os.Build.VERSION.SDK_INT < 8) 
            baseDir = Environment.getExternalStorageDirectory();
         else 
            baseDir = Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        

        if (baseDir == null)
            return Environment.getExternalStorageDirectory();

        Log.d(LOG_TAG, "Pictures folder: " + baseDir.getAbsolutePath());
        File fotorSDKFolder = new File(baseDir, FOLDER_NAME);

        if (fotorSDKFolder.exists())
            return fotorSDKFolder;
        if (fotorSDKFolder.mkdirs())
            return fotorSDKFolder;

        return Environment.getExternalStorageDirectory();
    

    class DownloadAsync extends AsyncTask<Uri, Void, Bitmap> implements
            OnCancelListener 

        ProgressDialog mProgress;
        private Uri mUri;

        @Override
        protected void onPreExecute() 
            super.onPreExecute();

            mProgress = new ProgressDialog(MainActivity.this);
            mProgress.setIndeterminate(true);
            mProgress.setCancelable(true);
            mProgress.setMessage("Loading image...");
            mProgress.setOnCancelListener(this);
            mProgress.show();
        

        @Override
        protected Bitmap doInBackground(Uri... params) 
            mUri = params[0];

            DisplayMetrics displayMetrics = getResources().getDisplayMetrics();

            int maxW = (int) displayMetrics.widthPixels;
            int maxH = (int) displayMetrics.heightPixels;

            Bitmap bitmap = BitmapDecodeUtils.decode(getApplicationContext(),
                    mUri, maxW, maxH);
            return bitmap;
        

        @Override
        protected void onPostExecute(Bitmap result) 
            super.onPostExecute(result);

            if (mProgress.getWindow() != null) 
                mProgress.dismiss();
            

            if (result != null) 
                setImageURI(mUri, result);
             else 
                Toast.makeText(MainActivity.this,
                        "Failed to load image " + mUri, Toast.LENGTH_SHORT)
                        .show();
            
        

        @Override
        public void onCancel(DialogInterface dialog) 
            Log.i(LOG_TAG, "onProgressCancel");
            this.cancel(true);
        

        @Override
        protected void onCancelled() 
            super.onCancelled();
            Log.i(LOG_TAG, "onCancelled");
        

    

错误

04-08 14:52:38.456: E/test(4457): Exception
04-08 14:52:38.457: D/dalvikvm(4457): threadid=19: notify debugger
04-08 14:52:38.457: D/dalvikvm(4457): threadid=19 (FotorAsyncTask #3): calling run()
04-08 14:52:38.465: E/AndroidRuntime(4457): FATAL EXCEPTION: FotorAsyncTask #2
04-08 14:52:38.465: E/AndroidRuntime(4457): java.lang.RuntimeException: An error occured while executing doInBackground()
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.everimaging.fotorsdk.utils.d.done(Unknown Source)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.everimaging.fotorsdk.utils.e.run(Unknown Source)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at java.lang.Thread.run(Thread.java:838)
04-08 14:52:38.465: E/AndroidRuntime(4457): Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.google.gson.Gson.fromJson(Gson.java:803)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.google.gson.Gson.fromJson(Gson.java:741)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.everimaging.fotorsdk.feature.StickersFeature.a(Unknown Source)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.everimaging.fotorsdk.feature.StickersFeature.D(Unknown Source)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.everimaging.fotorsdk.feature.StickersFeature.k(Unknown Source)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.everimaging.fotorsdk.feature.StickersFeature$a.doInBackground(Unknown Source)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.everimaging.fotorsdk.utils.c.call(Unknown Source)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
04-08 14:52:38.465: E/AndroidRuntime(4457):     ... 4 more
04-08 14:52:38.465: E/AndroidRuntime(4457): Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374)
04-08 14:52:38.465: E/AndroidRuntime(4457):     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165)
04-08 14:52:38.465: E/AndroidRuntime(4457):     ... 12 more
04-08 14:52:38.548: D/FotorContentProvider(4457): delete->uri:content://com.example.fotorsdkdemo.FotorContentProvider/sessions/fsid/fotor_api_key,selection:null,args:null, 

我是 android 新手,所以我不能完全理解这些错误是什么意思。如果有人可以帮助我,那就太好了。 没关系

【问题讨论】:

【参考方案1】:

你的 Logcat 说:

原因:java.lang.IllegalStateException: 预期 BEGIN_OBJECT 但 在第 1 行第 2 列是 BEGIN_ARRAY

您正在尝试将 json 数据解析为 Object,但 json 数据是 Array

你需要解决这个问题。

【讨论】:

以上是关于一些 logcat 错误 - 致命异常的主要内容,如果未能解决你的问题,请参考以下文章

线程以未捕获的异常退出,AyncTask #2 致命错误

如何在致命信号 11 之后使用 logcat 中的输出来找出我在 android 本机代码中从哪里得到错误?

PHPUnit 显示抛出致命错误异常的传递方法

Logcat 错误运行时异常,无法启动活动

android警报对话框错误

致命错误:未捕获的异常 PAYPAL