Android 中的意外 ArrayIndexOutOfBoundsException
Unexpected ArrayIndexOutOfBoundsException in Android
我的应用程序抛出意外的 ArrayIndexOutOfBoundsException,甚至没有告诉我抛出错误的行号。我尝试使用 Log 来放置消息来检查代码在哪里损坏,我发现数组大小为 5,但错误显示 java.lang.ArrayIndexOutOfBoundsException: length=4;索引=4
我正在使用 intent 打开相机:
File file = createImageFile();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Uri uri;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
uri = FileProvider.getUriForFile(pdf_viewer.this, BuildConfig.APPLICATION_ID + ".provider", file);
else
uri = Uri.fromFile(file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(cameraIntent, REQUEST_CODE);
而我的 onActivityResult 代码是:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK)
{
try {
new addImageInBack().execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这是一个 AsyncMethod,我的代码每次都会出错:
Log.e("1 - imgRotComp", " OK ");
ArrayList<String> img_paths = send_pdf_images;
File f = new File(Environment.getExternalStorageDirectory(),"/CamScan/.tempFiles");
if(!f.exists())
{
f.mkdirs();
}
Log.e("a", "OK" + img_paths.size());
for(int i = 0 ; i < img_paths.size() ; i++)
{
Log.e("b", "OK "+img_paths.size());
int orientation = 0;
try
{
Log.e("c", "OK");
ExifInterface oldExif = new ExifInterface(send_pdf_images.get(i));
orientation = oldExif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
}
catch (Exception e)
{
e.printStackTrace();
}
Log.e("d", "OK");
File a_file = new File(img_paths.get(i));
Bitmap a_bitmap = BitmapFactory.decodeFile(a_file.getAbsolutePath());
float a_op_width = a_bitmap.getWidth();
float a_op_height = a_bitmap.getHeight();
if (a_op_width < 1500 && orientation == 0)
continue;
Log.e("e", "OK");
if(orientation == 6 || orientation == 3 || orientation == 8)
{
Matrix rotateMatrix = new Matrix();
if (orientation == 6)
rotateMatrix.postRotate(90);
else if (orientation == 3)
rotateMatrix.postRotate(180);
else if (orientation == 8)
rotateMatrix.postRotate(270);
Bitmap rotatedBitmap = Bitmap.createBitmap(a_bitmap, 0, 0, a_bitmap.getWidth(), a_bitmap.getHeight(), rotateMatrix, false);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
try
{
Calendar c = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("d-M-yy-H-m-s", Locale.getDefault());
String dateTime = dateFormat.format(c.getTime());
dateTime = dateTime.replace("-", "");
File temp_file = new File(f.toString() + "/", dateTime + ".jpg");
temp_file.createNewFile();
FileOutputStream fo = new FileOutputStream(temp_file);
fo.write(bytes.toByteArray());
fo.close();
Uri uri = Uri.fromFile(temp_file);
String realPath = getRealPathFromURI(uri);
Log.e("l1","OK");
send_pdf_images.remove(i);
send_pdf_images.add(i, realPath);
Log.e("l2","OK");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
奇怪的是,每次我点击第 4 张图片时,我的代码都会出错,但它工作得很好。 t 在行 Log.e("d", "OK"); 和 Log.e("e", "OK") 之间中断; (仅在第 4 个图像点击期间)。
这是我的完整日志:
E/a: OK5
E/b: OK 5
E/c: OK
E/d: OK
E/b: OK 5
E/c: OK
E/d: OK
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.camscan, PID: 27178
java.lang.ArrayIndexOutOfBoundsException: length=4; index=4
at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6917)
at android.widget.GridView.layoutChildren(GridView.java:1268)
at android.widget.AbsListView.onLayout(AbsListView.java:2165)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1083)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1565)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1565)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:788)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2830)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2357)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1493)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7283)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:696)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6912)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:860)
I/Process: Sending signal. PID: 27178 SIG: 9
Process 27178 terminated.
编辑:
PDFViewAdapter.java
package com.example.camscan;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.ArrayList;
public class PDFViewAdapter extends ArrayAdapter<String> {
Context context;
ViewHolder viewHolder;
ArrayList<String> pdf_images = new ArrayList<>();
public PDFViewAdapter(Context context, ArrayList<String> pdf_images) {
super(context, R.layout.pdf_image_view, pdf_images);
this.pdf_images = pdf_images;
this.context = context;
}
@Override
public int getCount() {
return pdf_images.size();
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return pdf_images.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(R.layout.pdf_image_view, parent, false);
viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.pdfiv);
viewHolder.tv = (TextView)convertView.findViewById(R.id.pdftv);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv.setTag(position);
Glide.with(context).load(pdf_images.get(position))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(viewHolder.iv_image);
viewHolder.tv.setText(""+(position + 1));
return convertView;
}
private static class ViewHolder {
ImageView iv_image;
TextView tv;
}
}
这可能是什么原因造成的?
谢谢
我认为问题出在这一行:
File a_file = new File(img_paths.get(i));
尝试记录 i 的值并尝试 i -1。
错误说你想要数组的第四个元素,但数组长度只有 4:0,1,2,3.
我得到了解决方案!我犯了一个非常非常愚蠢的错误。假设我的网格视图中有 4 张图像,当我从相机中单击新图像并且在我的 onActivityResult 中收到单击的图像时,我应该用新图像更新我的网格视图,即我应该再次调用:
adapter = new PDFViewAdapter(pdf_viewer.this, pdf_viewer.send_pdf_images);
gridView.setAdapter(adapter);
然后我应该调用我在问题中发布的 AsyncMethod(引发错误的地方)。但是我在没有更新我的适配器的情况下调用了 AsyncMethod,并且我再次访问了我的 AsyncMethod 中的网格视图元素。这就是它一次又一次地显示相同的 ArrayIndexOutOfBoundsException 的原因。
非常感谢@Akash Raghav 和@julianpjp 的时间和支持。
我的应用程序抛出意外的 ArrayIndexOutOfBoundsException,甚至没有告诉我抛出错误的行号。我尝试使用 Log 来放置消息来检查代码在哪里损坏,我发现数组大小为 5,但错误显示 java.lang.ArrayIndexOutOfBoundsException: length=4;索引=4
我正在使用 intent 打开相机:
File file = createImageFile();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Uri uri;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
uri = FileProvider.getUriForFile(pdf_viewer.this, BuildConfig.APPLICATION_ID + ".provider", file);
else
uri = Uri.fromFile(file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(cameraIntent, REQUEST_CODE);
而我的 onActivityResult 代码是:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK)
{
try {
new addImageInBack().execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这是一个 AsyncMethod,我的代码每次都会出错:
Log.e("1 - imgRotComp", " OK ");
ArrayList<String> img_paths = send_pdf_images;
File f = new File(Environment.getExternalStorageDirectory(),"/CamScan/.tempFiles");
if(!f.exists())
{
f.mkdirs();
}
Log.e("a", "OK" + img_paths.size());
for(int i = 0 ; i < img_paths.size() ; i++)
{
Log.e("b", "OK "+img_paths.size());
int orientation = 0;
try
{
Log.e("c", "OK");
ExifInterface oldExif = new ExifInterface(send_pdf_images.get(i));
orientation = oldExif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
}
catch (Exception e)
{
e.printStackTrace();
}
Log.e("d", "OK");
File a_file = new File(img_paths.get(i));
Bitmap a_bitmap = BitmapFactory.decodeFile(a_file.getAbsolutePath());
float a_op_width = a_bitmap.getWidth();
float a_op_height = a_bitmap.getHeight();
if (a_op_width < 1500 && orientation == 0)
continue;
Log.e("e", "OK");
if(orientation == 6 || orientation == 3 || orientation == 8)
{
Matrix rotateMatrix = new Matrix();
if (orientation == 6)
rotateMatrix.postRotate(90);
else if (orientation == 3)
rotateMatrix.postRotate(180);
else if (orientation == 8)
rotateMatrix.postRotate(270);
Bitmap rotatedBitmap = Bitmap.createBitmap(a_bitmap, 0, 0, a_bitmap.getWidth(), a_bitmap.getHeight(), rotateMatrix, false);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
try
{
Calendar c = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("d-M-yy-H-m-s", Locale.getDefault());
String dateTime = dateFormat.format(c.getTime());
dateTime = dateTime.replace("-", "");
File temp_file = new File(f.toString() + "/", dateTime + ".jpg");
temp_file.createNewFile();
FileOutputStream fo = new FileOutputStream(temp_file);
fo.write(bytes.toByteArray());
fo.close();
Uri uri = Uri.fromFile(temp_file);
String realPath = getRealPathFromURI(uri);
Log.e("l1","OK");
send_pdf_images.remove(i);
send_pdf_images.add(i, realPath);
Log.e("l2","OK");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
奇怪的是,每次我点击第 4 张图片时,我的代码都会出错,但它工作得很好。 t 在行 Log.e("d", "OK"); 和 Log.e("e", "OK") 之间中断; (仅在第 4 个图像点击期间)。
这是我的完整日志:
E/a: OK5
E/b: OK 5
E/c: OK
E/d: OK
E/b: OK 5
E/c: OK
E/d: OK
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.camscan, PID: 27178
java.lang.ArrayIndexOutOfBoundsException: length=4; index=4
at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6917)
at android.widget.GridView.layoutChildren(GridView.java:1268)
at android.widget.AbsListView.onLayout(AbsListView.java:2165)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1083)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1565)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1565)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:788)
at android.view.View.layout(View.java:20680)
at android.view.ViewGroup.layout(ViewGroup.java:6197)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2830)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2357)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1493)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7283)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:696)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6912)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:860)
I/Process: Sending signal. PID: 27178 SIG: 9
Process 27178 terminated.
编辑: PDFViewAdapter.java
package com.example.camscan;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.ArrayList;
public class PDFViewAdapter extends ArrayAdapter<String> {
Context context;
ViewHolder viewHolder;
ArrayList<String> pdf_images = new ArrayList<>();
public PDFViewAdapter(Context context, ArrayList<String> pdf_images) {
super(context, R.layout.pdf_image_view, pdf_images);
this.pdf_images = pdf_images;
this.context = context;
}
@Override
public int getCount() {
return pdf_images.size();
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return pdf_images.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(R.layout.pdf_image_view, parent, false);
viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.pdfiv);
viewHolder.tv = (TextView)convertView.findViewById(R.id.pdftv);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv.setTag(position);
Glide.with(context).load(pdf_images.get(position))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(viewHolder.iv_image);
viewHolder.tv.setText(""+(position + 1));
return convertView;
}
private static class ViewHolder {
ImageView iv_image;
TextView tv;
}
}
这可能是什么原因造成的? 谢谢
我认为问题出在这一行:
File a_file = new File(img_paths.get(i));
尝试记录 i 的值并尝试 i -1。 错误说你想要数组的第四个元素,但数组长度只有 4:0,1,2,3.
我得到了解决方案!我犯了一个非常非常愚蠢的错误。假设我的网格视图中有 4 张图像,当我从相机中单击新图像并且在我的 onActivityResult 中收到单击的图像时,我应该用新图像更新我的网格视图,即我应该再次调用:
adapter = new PDFViewAdapter(pdf_viewer.this, pdf_viewer.send_pdf_images);
gridView.setAdapter(adapter);
然后我应该调用我在问题中发布的 AsyncMethod(引发错误的地方)。但是我在没有更新我的适配器的情况下调用了 AsyncMethod,并且我再次访问了我的 AsyncMethod 中的网格视图元素。这就是它一次又一次地显示相同的 ArrayIndexOutOfBoundsException 的原因。
非常感谢@Akash Raghav 和@julianpjp 的时间和支持。