【问题标题】:App crashes at image upload because of bitmap and nullpointer由于位图和空指针,应用程序在图像上传时崩溃
【发布时间】:2019-12-14 21:27:45
【问题描述】:

我正在编写一个应用程序来将图像从画廊和相机上传到我的服务器 我遇到的问题是,当我从相机拍照并单击上传按钮时,它会从应用程序中崩溃 根据调试日志,它与指向空对象引用的位图以及位图未能解码流有关

有一些关于 SO 的答案,但到目前为止还没有工作

错误日志

   E/BitmapFactory: Unable to decode stream: java.lang.NullPointerException
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.smartpractice.myapplication, PID: 18010
    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
        at com.smartpractice.myapplication.MainActivity.upload(MainActivity.java:79)
        at com.smartpractice.myapplication.MainActivity.access$100(MainActivity.java:41)
        at com.smartpractice.myapplication.MainActivity$2.onClick(MainActivity.java:67)
        at android.view.View.performClick(View.java:6663)
        at android.view.View.performClickInternal(View.java:6635)
        at android.view.View.access$3100(View.java:794)
        at android.view.View$PerformClick.run(View.java:26199)
        at android.os.Handler.handleCallback(Handler.java:907)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7593)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

活动 java

public class MainActivity extends Activity {

Button btpic, btnup;
private Uri fileUri;
String picturePath;
Uri selectedImage;
Bitmap photo;
String ba1;
public static String URL = "Paste your URL here";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btpic = (Button) findViewById(R.id.cpic);
    btpic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            clickpic();
        }
    });

    btnup = (Button) findViewById(R.id.up);
    btnup.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            upload();
        }
    });
}

private void upload() {
    // Image location URL
    Log.e("path", "----------------" + picturePath);

    // Image
    Bitmap bm = BitmapFactory.decodeFile(picturePath);
    ByteArrayOutputStream bao = new ByteArrayOutputStream();
    bm.compress(Bitmap.CompressFormat.JPEG, 0, bao);
    byte[] ba = bao.toByteArray();
    ba1 = Base64.encodeToString(ba, Base64.NO_WRAP);

    Log.e("base64", "-----" + ba1);

    // Upload image to server
    new uploadToServer().execute();

}

private void clickpic() {
    // Check Camera
    if (getApplicationContext().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA)) {
        // Open default camera
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        // start the image capture Intent
        startActivityForResult(intent, 100);

    } else {
        Toast.makeText(getApplication(), "Camera not supported", Toast.LENGTH_LONG).show();
    }
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 100 && resultCode == RESULT_OK) {

        selectedImage = data.getData();
        photo = (Bitmap) data.getExtras().get("data");




        Bitmap photo = (Bitmap) data.getExtras().get("data");
        ImageView imageView = (ImageView) findViewById(R.id.Imageprev);
        imageView.setImageBitmap(photo);
    }
}

public class uploadToServer extends AsyncTask<Void, Void, String> {

    private ProgressDialog pd = new ProgressDialog(MainActivity.this);
    protected void onPreExecute() {
        super.onPreExecute();
        pd.setMessage("Wait image uploading!");
        pd.show();
    }

    @Override
    protected String doInBackground(Void... params) {

        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("base64", ba1));
        nameValuePairs.add(new BasicNameValuePair("ImageName", System.currentTimeMillis() + ".jpg"));
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(URL);
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            String st = EntityUtils.toString(response.getEntity());
            Log.v("log_tag", "In the try Loop" + st);

        } catch (Exception e) {
            Log.v("log_tag", "Error in http connection " + e.toString());
        }
        return "Success";

    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        pd.hide();
        pd.dismiss();
    }
}

【问题讨论】:

  • 您的图片路径为空,因此您的位图为空,然后您尝试压缩空位图因此崩溃
  • 在做这样的事情时,你应该把它放在一个try catch中,这样即使出现问题,你的应用程序至少不会崩溃。也尝试使用BitmapFactory.decodeFile(File(picturepath)) 而不是BitmapFactory.decodeFile(picturePath)
  • @NikosHidalgo 我对 java 和 android 很陌生,你能帮我解决这个问题吗?
  • 创建照片时在 onActivityResult 中,获取它的路径 (stackoverflow.com/questions/15432592/…) 并将其保存到图片路径。那应该可以解决您的崩溃问题。尽管如果用户在拍摄任何照片之前可以单击上传,您的应用仍然容易崩溃。这就是为什么您要么检查空值,要么将图片路径作为参数添加到上传方法中,并在知道您有图片路径值时调用它。
  • @HartWoom 将 BitmapFactory.decodeFile(picturePath) 更改为 BitmapFactory.decodeFile(File(picturepath)) 给了我“METHOD CALL EXPECTED”错误任何解决方案?

标签: java android bitmap crash


【解决方案1】:
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

       if (requestCode==REQUEST_CAMERA)
        {
            Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
            File destination = new File(Environment.getExternalStorageDirectory(),"temp.jpg");
            FileOutputStream fo;
            try {
                fo = new FileOutputStream(destination);
                fo.write(bytes.toByteArray());
                fo.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

           new uploadFileToServerTask().execute(destination.getAbsolutePath());
        }
    }

上传文件到服务器

 private class uploadFileToServerTask extends AsyncTask<String, String, Object> {
        @Override
        protected String doInBackground(String... args) {
            try {
                String lineEnd = "\r\n";
                String twoHyphens = "--";
                String boundary = "*****";
                int bytesRead, bytesAvailable, bufferSize;
                byte[] buffer;
                @SuppressWarnings("PointlessArithmeticExpression")
                int maxBufferSize = 1 * 1024 * 1024;


                java.net.URL url = new URL((ApplicationConstant.UPLOAD_IMAGE_URL) + IMAGE + customer_id);
                Log.d(ApplicationConstant.TAG, "url " + url);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                // Allow Inputs &amp; Outputs.
                connection.setDoInput(true);
                connection.setDoOutput(true);
                connection.setUseCaches(false);

                // Set HTTP method to POST.
                connection.setRequestMethod("POST");

                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

                FileInputStream fileInputStream;
                DataOutputStream outputStream;
                {
                    outputStream = new DataOutputStream(connection.getOutputStream());

                    outputStream.writeBytes(twoHyphens + boundary + lineEnd);
                    String filename = args[0];
                    outputStream.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + filename + "\"" + lineEnd);
                    outputStream.writeBytes(lineEnd);
                    Log.d(ApplicationConstant.TAG, "filename " + filename);

                    fileInputStream = new FileInputStream(filename);

                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);

                    buffer = new byte[bufferSize];

                    // Read file
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                    while (bytesRead > 0) {
                        outputStream.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    }
                    outputStream.writeBytes(lineEnd);
                    outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                }

                int serverResponseCode = connection.getResponseCode();
                String serverResponseMessage = connection.getResponseMessage();
                Log.d("serverResponseCode", "" + serverResponseCode);
                Log.d("serverResponseMessage", "" + serverResponseMessage);

                fileInputStream.close();
                outputStream.flush();
                outputStream.close();

                if (serverResponseCode == 200) {
                    return "true";
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "false";
        }

        @Override
        protected void onPostExecute(Object result) {

        }
    }

【讨论】:

  • 感谢您的帮助,只有一个问题 APPLICATIONCONSTANT 给我无法解决符号错误?以及 IMAGE 和 customer_id 中的相同错误
  • java.net.URL url = 你的基本 url+图片 url;。希望现在有帮助。请用您自己的变量替换变量
  • 我很抱歉,但我不明白我对 java 和 android 以及一般编码都很陌生
  • java.net.URL url= URL+ selectedImage;像这样的东西?因为它说它需要一个 URL,但这显然是一个字符串
  • 是的,请不要与您的后端人员一起使用。那你将如何发送图像
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
相关资源
最近更新 更多