【问题标题】:Unexpected ArrayIndexOutOfBoundsException in AndroidAndroid中意外的ArrayIndexOutOfBoundsException
【发布时间】:2020-06-20 17:20:08
【问题描述】:

我的应用程序抛出了意外的 ArrayIndexOutOfBoundsException,甚至没有告诉我抛出错误的行号。我尝试使用 Log 放置消息以检查代码在哪里损坏,我发现数组大小为 5 但错误显示 java.lang.ArrayIndexOutOfBoundsException: length=4;索引=4

我正在使用意图打开相机:

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();
                    }

                }
          }

奇怪的部分是我的代码每次点击第四张图片时都会中断,之前它工作得很好。 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;
    }

}

这可能是什么原因? 谢谢

【问题讨论】:

  • 你能试试调试模式吗,手动单步调试代码至少知道在哪一行之后崩溃以缩小范围。
  • @AkashRaghav 由于网格视图问题,它正在崩溃。请参阅我的编辑。这是我反复运行后发现的
  • 能否贴出网格视图适配器/相关代码。
  • 我现在做到了。当我第一次在 Activity onCreate 上调用它时,这似乎工作正常,我从图库中选择了图像。但是,当我从相机单击新图像以动态将新图像添加到网格视图时,我正在从我的 Activity onResult 调用相同的函数,然后它就崩溃了
  • 我得到了解决方案@AkashRaghav。看我的回答。谢谢你的时间:-)

标签: android indexoutofboundsexception


【解决方案1】:

我找到了解决方案!我犯了一个非常非常愚蠢的错误。假设我的网格视图中有 4 个图像,当我从相机单击新图像并且在 onActivityResult 中收到单击的图像时,我应该使用新图像更新我的网格视图,即,我应该再次调用:

adapter = new PDFViewAdapter(pdf_viewer.this, pdf_viewer.send_pdf_images);
gridView.setAdapter(adapter);

然后我应该调用我在问题中发布的 AsyncMethod(引发错误的位置)。但是我在没有更新适配器的情况下调用了 AsyncMethod,并且我再次访问了 AsyncMethod 中的网格视图元素。这就是它一次又一次地显示相同的 ArrayIndexOutOfBoundsException 的原因。

非常感谢 @Akash Raghav 和 @julianpjp 的时间和支持。

【讨论】:

    【解决方案2】:

    我认为问题出在这一行:

     File a_file = new File(img_paths.get(i));
    

    尝试记录 i 的值并尝试 i -1。 错误说你想要数组的第四个元素但是数组长度只有4:0,1,2,3。

    【讨论】:

    • 这行不通。如果我放 i-1 它肯定会超出界限,因为我的起始 i 值为 0。它会在您的更新后变为 -1。
    • 问题似乎出在我正在对捕获的图像进行膨胀的网格视图上。我已将网格视图的高度和宽度设置为一次只有 4 个项目完全可见。因此,当我单击第 5 张图像并尝试对其进行充气时,它会崩溃。但是如果我在点击第四张图片后手动滚动到底部,它就可以正常工作了。我该如何纠正这个问题。
    猜你喜欢
    • 2010-11-28
    • 2013-04-30
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    相关资源
    最近更新 更多