Создал приложение, которое грузит изображения на сервер, использую библиотеку Retrofit.
Layout файл:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.haykmkrtchyan.retrofitimageupload.MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="300dp"
android:layout_height="250dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="15dp"
android:contentDescription="@string/Image"
android:visibility="gone" />
<EditText
android:id="@+id/img_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:hint="@string/Title"
android:visibility="gone" />
<Button
android:id="@+id/chooseBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_marginTop="25dp"
android:text="@string/Choose" />
<Button
android:id="@+id/uploadBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_marginTop="15dp"
android:enabled="false"
android:text="@string/Upload" />
Есть 3 класса и 1 интерфейс.
ApiClient.java:
public class ApiClient {
private static final String BaseURL = "http://10.0.2.2/imageupload/";
private static Retrofit retrofit;
public static Retrofit getApiClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BaseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
ImageClass.java:
public class ImageClass {
@SerializedName("title")
private String Title;
@SerializedName("image")
private String Image;
@SerializedName("response")
private String Response;
public String getResponse() {
return Response;
}
}
ApiInterface.java:
public interface ApiInterface {
@FormUrlEncoded
@POST("upload.php")
Call<ImageClass> uploadImage(@Field("title") String title, @Field("image") String image);
}
MainActivity.java:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText title;
private Button choose, upload;
private ImageView image;
private static final int IMG_REQUEST = 777;
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
title = findViewById(R.id.img_title);
choose = findViewById(R.id.chooseBtn);
upload = findViewById(R.id.uploadBtn);
image = findViewById(R.id.imageView);
choose.setOnClickListener(this);
upload.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.chooseBtn:
selectImage();
break;
case R.id.uploadBtn:
uploadImage();
break;
}
}
private void selectImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, IMG_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMG_REQUEST && resultCode == RESULT_OK && data != null) {
Uri path = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), path);
image.setImageBitmap(bitmap);
image.setVisibility(View.VISIBLE);
title.setVisibility(View.VISIBLE);
choose.setEnabled(false);
upload.setEnabled(true);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void uploadImage() {
String Image = imageToString();
String Title = title.getText().toString();
ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<ImageClass> call = apiInterface.uploadImage(Title, Image);
call.enqueue(new Callback<ImageClass>() {
@Override
public void onResponse(@NonNull Call<ImageClass> call, @NonNull Response<ImageClass> response) {
ImageClass imageClass = response.body();
Toast.makeText(MainActivity.this, "Server Response: " + imageClass, Toast.LENGTH_SHORT).show();
image.setVisibility(View.GONE);
title.setVisibility(View.GONE);
choose.setEnabled(true);
upload.setEnabled(false);
title.setText("");
}
@Override
public void onFailure(@NonNull Call<ImageClass> call, @NonNull Throwable t) {
}
});
}
private String imageToString(){
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
//bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
byte[] imgByte = outputStream.toByteArray();
return Base64.encodeToString(imgByte, Base64.DEFAULT);
}
}
Есть 2 кнопки, 1 на выбор картинки, а 2 для отправки на сервер. Сервер написан руками, там все работает. Но когда нажимаю на отправку, то происходит краш - проблема с памятью.
Как решить проблему?
Вот логи:
01-07 14:25:10.142 3684-3684/? E/memtrack: Couldn't load memtrack module (No such file or directory)
01-07 14:25:10.142 3684-3684/? E/android.os.Debug: failed to load memtrack module: -2
01-07 14:25:11.674 3704-3704/? E/memtrack: Couldn't load memtrack module (No such file or directory)
01-07 14:25:11.674 3704-3704/? E/android.os.Debug: failed to load memtrack module: -2
01-07 14:25:11.830 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/dalvikvm: Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
01-07 14:25:13.302 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/OpenGLRenderer: Getting MAX_TEXTURE_SIZE from GradienCache
01-07 14:25:13.302 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/OpenGLRenderer: MAX_TEXTURE_SIZE: 16384
01-07 14:25:13.310 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/OpenGLRenderer: Getting MAX_TEXTURE_SIZE from Caches::initConstraints()
01-07 14:25:13.314 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/OpenGLRenderer: MAX_TEXTURE_SIZE: 16384
01-07 14:25:18.298 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/dalvikvm: Could not find class 'android.support.v4.app.ActivityCompat$SharedElementCallback23Impl', referenced from method android.support.v4.app.ActivityCompat.setEnterSharedElementCallback
01-07 14:25:18.298 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/dalvikvm: Could not find class 'android.support.v4.app.ActivityCompat$SharedElementCallback21Impl', referenced from method android.support.v4.app.ActivityCompat.setEnterSharedElementCallback
01-07 14:25:18.298 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/dalvikvm: Could not find class 'android.support.v4.app.ActivityCompat$SharedElementCallback23Impl', referenced from method android.support.v4.app.ActivityCompat.setExitSharedElementCallback
01-07 14:25:18.298 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/dalvikvm: Could not find class 'android.support.v4.app.ActivityCompat$SharedElementCallback21Impl', referenced from method android.support.v4.app.ActivityCompat.setExitSharedElementCallback
01-07 14:25:46.369 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/dalvikvm-heap: Out of memory on a 16775180-byte allocation.
01-07 14:25:46.377 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/dalvikvm-heap: Out of memory on a 8386572-byte allocation.
01-07 14:25:46.381 3714-3714/com.example.haykmkrtchyan.retrofitimageupload E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.haykmkrtchyan.retrofitimageupload, PID: 3714
java.lang.OutOfMemoryError
at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:122)
at com.example.haykmkrtchyan.retrofitimageupload.MainActivity.imageToString(MainActivity.java:120)
at com.example.haykmkrtchyan.retrofitimageupload.MainActivity.uploadImage(MainActivity.java:92)
at com.example.haykmkrtchyan.retrofitimageupload.MainActivity.onClick(MainActivity.java:55)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
01-07 14:25:58.317 2214-2287/system_process E/InputDispatcher: channel '52a6901c PopupWindow:52877f88 (server)' ~ Channel is unrecoverably broken and will be disposed!
01-07 14:25:58.317 2214-2287/system_process E/InputDispatcher: channel '529e00c4 com.example.haykmkrtchyan.retrofitimageupload/com.example.haykmkrtchyan.retrofitimageupload.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
Некоторое время назад краш не происходил, но и на сервер не отправлял. Нажал отправить, происходит freeze на 5-10 секунд и ничего, как был так и остался.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Пишу клиент — серверное приложениеДля учета подключившихся клиентов хочу использовать ArrayList
Как отсортировать массив по числам, которые идут перед URlДопустим есть данные:
Проблема следующаяЕсть сервлет на сервере, который принимает данные в формате json
Изменяю context-root проекта через properties->Web Project Settings с training на SpringMVCНо приложение всё равно работает только по этому адресу, почему?