一些 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 错误 - 致命异常的主要内容,如果未能解决你的问题,请参考以下文章