简体   繁体   English

与小尺寸图像完美配合,“但是在将大尺寸图像上传到服务器时会出现NullPointerException错误”。为什么?

[英]Works perfectly with small sized images, “but gives NullPointerException error when uploading large sized image to server”.why?

I am trying to make a feature of upload image to server.For that i am using hostinger server and WinScp as file manager and a php Api for upload.To make this service i have used retrofit2 library . 我正在尝试将图像上传到server。为此,我使用托管服务器和WinScp作为文件管理器,并使用php Api上传。要使用此服务,我使用了retrofit2

My code works perfectly when user chooses small sized image from gallery.But app gets crashed and gives error of NullPointerException when user chooses large sized image from gallery .Why this is happening i don't understand.Please help me to solve. 当用户从图库中选择小尺寸图像时,我的代码可以正常工作。但是当用户从图库中选择大尺寸图像时,应用程序崩溃并给出NullPointerException错误。为什么这种情况我不明白。请帮助我解决。

Stack trace:(when user selects large sized image and clicks upload) 堆栈跟踪:(当用户选择大尺寸图像并单击上传时)

06-25 01:03:28.589 23155-23155/h.safmical.swipe I/Choreographer: Skipped 1122 frames!  The application may be doing too much work on its main thread.
06-25 01:03:33.451 23155-23162/h.safmical.swipe W/art: Suspending all threads took: 5.917ms
06-25 01:03:47.595 23155-23155/h.safmical.swipe E/saf: in onresponse
06-25 01:03:47.597 23155-23155/h.safmical.swipe D/AndroidRuntime: Shutting down VM
06-25 01:03:47.601 23155-23155/h.safmical.swipe E/AndroidRuntime: FATAL EXCEPTION: main
                                                                  Process: h.safmical.swipe, PID: 23155
                                                                  java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String h.safmical.swipe.ImageClass.getResponse()' on a null object reference
                                                                      at h.safmical.swipe.retrofit_img_upload$3.onResponse(retrofit_img_upload.java:94)
                                                                      at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
                                                                      at android.os.Handler.handleCallback(Handler.java:746)
                                                                      at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                      at android.os.Looper.loop(Looper.java:148)
                                                                      at android.app.ActivityThread.main(ActivityThread.java:5443)
                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

My coding files: 我的编码文件:

MainActivity: 主要活动:

retrofit_img_upload.java: retrofit_img_upload.java:

package h.safmical.swipe;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class retrofit_img_upload extends AppCompatActivity {
    private EditText img_title;
    private Button choose, upload;
    private ImageView img;
    private static final int IMG_REQUEST = 777;
    private Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_retrofit_img_upload);
        Log.e("saf", "in oncrate of main");
        img_title = (EditText) findViewById(R.id.image_title);
        choose = (Button) findViewById(R.id.choose);
        upload = (Button) findViewById(R.id.upload);
        img = (ImageView) findViewById(R.id.imageview);
        choose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectImage();

            }
        });
        upload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                uploadimg();
            }
        });
    }

    private void selectImage() {
        Log.e("saf", "in inselectimg");
        Intent i = new Intent();
        i.setType("image/*");
        i.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(i, IMG_REQUEST);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.e("saf", "in onactivityresult");
        if (requestCode == IMG_REQUEST && resultCode == RESULT_OK && data != null) {
            Uri path = data.getData();
            try {
                bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), path);
                img.setImageBitmap(bitmap);
                img.setVisibility(View.VISIBLE);
                img_title.setVisibility(View.VISIBLE);
                choose.setEnabled(false);
                upload.setEnabled(true);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void uploadimg() {
        String Image = imageToString();
        String Title = img_title.getText().toString();
        Image_ApiInterface apiInterface = Image_ApiClient.getApiclient().create(Image_ApiInterface.class);
        Call<ImageClass> call = apiInterface.uploadImage(Title, Image);
        call.enqueue(new Callback<ImageClass>() {
            @Override
            public void onResponse(Call<ImageClass> call, Response<ImageClass> response) {
                Log.e("saf", "in onresponse");
                ImageClass imageclass = response.body();
               Toast.makeText(retrofit_img_upload.this, "server response:" + imageclass.getResponse(), Toast.LENGTH_LONG).show();
                img.setVisibility(View.GONE);
                img_title.setVisibility(View.GONE);
                choose.setEnabled(true);
                upload.setEnabled(false);
                img_title.setText("");
            }

            @Override
            public void onFailure(Call<ImageClass> call, Throwable t) {
                Log.e("saf", "in onfailure");
                Log.e("saf", t.toString());

            }
        });
    }


    private String imageToString() {
        Log.e("saf", "in imagetostring");
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
        byte[] imgByte = byteArrayOutputStream.toByteArray();
        //Log.e("saf",Base64.encodeToString(imgByte,Base64.DEFAULT));
        return Base64.encodeToString(imgByte, Base64.DEFAULT);
    }
}

Class to create an instance of Retrofit: 创建Retrofit实例的类:

Image_ApiClient.java: Image_ApiClient.java:

package h.safmical.swipe;

import android.util.Log;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by hadvani on 6/24/2017.
 */

public class Image_ApiClient {
    private static final String BaseUrl= "****************";
    private  static Retrofit retrofit;

    public static Retrofit getApiclient(){
        Log.e("saf","in getapiclient");
        if(retrofit==null){
            Log.e("saf","in if of get apiclient");
            retrofit=new Retrofit.Builder().baseUrl(BaseUrl).addConverterFactory(GsonConverterFactory.create()).build();
        }
        return retrofit;
    }
}

Interface to pass parameters to api: 将参数传递给api的接口:

Image_ApiInterface.java: Image_ApiInterface.java:

package h.safmical.swipe;

import android.util.Log;

import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
import retrofit2.http.Query;

/**
 * Created by hadvani on 6/24/2017.
 */

public interface Image_ApiInterface {

    @FormUrlEncoded
    @POST("upload.php")
    Call<ImageClass> uploadImage(@Field("title") String title, @Field("image") String image);

}

Class for Response: 回应类别:

ImageClass.java: ImageClass.java:

package h.safmical.swipe;

import com.google.gson.annotations.SerializedName;

/**
 * Created by hadvani on 6/24/2017.
 */

public class ImageClass {

    @SerializedName("title")
    private String Title;

    @SerializedName("image")
    private String Image;

    @SerializedName("response")
    private String Response;

    public String getResponse() {
        return Response;
    }
}

Xml file of retro_img_upload(MainActivity): retro_img_upload(MainActivity)的Xml文件:

activity_retrofit_img_upload.xml: activity_retrofit_img_upload.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="h.safmical.swipe.retrofit_img_upload">
    <ImageView
        android:layout_width="300dp"
        android:layout_height="250dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:id="@+id/imageview"
        android:visibility="gone"/>
<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/imageview"
    android:hint="Enter image title"
    android:layout_marginTop="20dp"
    android:id="@+id/image_title"
    android:visibility="gone"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/image_title"
        android:text="Choose image"
        android:layout_marginTop="25dp"
        android:id="@+id/choose"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/choose"
        android:text="upload image"
        android:layout_marginTop="25dp"
        android:id="@+id/upload"
        android:enabled="false"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"/>
</RelativeLayout>

PHP file to upload Image: PHP文件上传图片:

upload.php: upload.php的:

<?php
include 'confi.php';
  if($conn)
  {
   $title=$_POST['title'];
   $image=$_POST['image'];
  $upload_pathh = "uploads/$title.jpg";
   $upload_path = "***********/uploads/$title.jpg";

   $sql = "insert into imageinfo(title,path) values('$title','$upload_path');";
   if(mysqli_query($conn,$sql))
   {
   file_put_contents($upload_pathh,base64_decode($image));
   echo json_encode(array('response'=>"image uploaded successfully...."));
   }
   else
   {
       echo json_encode(array('response'=>"image upload failed...."));
   }   

   mysqli_close($conn);

  }
?>

I have listed all my coding files includes this feature of my application.Please help me to solve this.Thank you. 我已经列出了我所有的编码文件,包括我的应用程序的此功能。请帮助我解决此问题。谢谢。

Your imageclass object is null hence you are getting hence you are getting "attempt to invoke virtual method at ImageClass.getResponse()' on a null object reference". 您的imageclass对象为null,因此您将获得“尝试在null对象引用上在ImageClass.getResponse()处调用虚拟方法”的信息。 Make sure your url works, use postman or some other api test software. 确保您的网址有效,使用邮递员或其他一些api测试软件。

ImageClass imageclass = response.body();

That is because you need to resize your image before uploading. 那是因为您需要在上传之前调整图像大小。 Since the image you are trying to upload is too big and that is causing your android to consume a lot of memory. 由于您尝试上传的图片太大,导致您的Android占用大量内存。 Use a thread first of all as you can see in your error that is working too much on its main thread and that is the reason why you are getting null by the log 06-25 01:03:28.589 23155-23155/h.safmical.swipe I/Choreographer: Skipped 1122 frames! The application may be doing too much work on its main thread. 首先使用一个线程,正如您在错误中看到的那样,该错误在其主线程上工作过多,这就是为什么日志06-25 01:03:28.589 23155-23155/h.safmical.swipe I/Choreographer: Skipped 1122 frames! The application may be doing too much work on its main thread. 06-25 01:03:28.589 23155-23155/h.safmical.swipe I/Choreographer: Skipped 1122 frames! The application may be doing too much work on its main thread. and also use this 并用这个

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

so that you donot end up loading the big bitmap in your memory 这样您就不会最终将大位图加载到内存中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM