Từ chối re-init trên lớp thất bại trước đó trong OkHttp


22

Tôi đang cố gắng tải lên một hình ảnh đến máy chủ của mình bằng cách sử dụng phần cuối bình sẽ xử lý tệp để lưu trong thư mục và OkHttp trong Android. nhưng tôi gặp lỗi này trong Android:

I/art: Rejecting re-init on previously-failed class java.lang.Class<okhttp3.internal.platform.ConscryptPlatform$configureTrustManager$1>: java.lang.NoClassDefFoundError: Failed resolution of: Lorg/conscrypt/ConscryptHostnameVerifier;
        at okhttp3.internal.platform.android.SocketAdapter okhttp3.internal.platform.android.ConscryptSocketAdapter.buildIfSupported() (ConscryptSocketAdapter.kt:64)
        at void okhttp3.internal.platform.AndroidPlatform.<init>() (AndroidPlatform.kt:45)
        at okhttp3.internal.platform.Platform okhttp3.internal.platform.AndroidPlatform$Companion.buildIfSupported() (AndroidPlatform.kt:239)
        at okhttp3.internal.platform.Platform okhttp3.internal.platform.Platform$Companion.findPlatform() (Platform.kt:211)
        at okhttp3.internal.platform.Platform okhttp3.internal.platform.Platform$Companion.access$findPlatform(okhttp3.internal.platform.Platform$Companion) (Platform.kt:179)
        at void okhttp3.internal.platform.Platform.<clinit>() (Platform.kt:180)
        at void okhttp3.OkHttpClient.<init>(okhttp3.OkHttpClient$Builder) (OkHttpClient.kt:219)
        at void okhttp3.OkHttpClient.<init>() (OkHttpClient.kt:211)
        at void com.example.swiftpinx.Activity.AddMediaActivity.onClick(android.view.View) (AddMediaActivity.java:207)
        at boolean android.view.View.performClick() (View.java:5637)
        at void android.view.View$PerformClick.run() (View.java:22429)
        at void android.os.Handler.handleCallback(android.os.Message) (Handler.java:751)
        at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:95)
        at void android.os.Looper.loop() (Looper.java:154)
        at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6119)
        at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2)
        at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:886)
        at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:776)
    Caused by: java.lang.ClassNotFoundException: Didn't find class "org.conscrypt.ConscryptHostnameVerifier" on path: DexPathList[[zip file "/data/app/com.example.swiftpinx-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.swiftpinx-1/lib/x86, /system/lib, /vendor/lib]]
        at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:56)
        at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:380)
        at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
        at okhttp3.internal.platform.android.SocketAdapter okhttp3.internal.platform.android.ConscryptSocketAdapter.buildIfSupported() (ConscryptSocketAdapter.kt:64)
        at void okhttp3.internal.platform.AndroidPlatform.<init>() (AndroidPlatform.kt:45)
        at okhttp3.internal.platform.Platform okhttp3.internal.platform.AndroidPlatform$Companion.buildIfSupported() (AndroidPlatform.kt:239)
        at okhttp3.internal.platform.Platform okhttp3.internal.platform.Platform$Companion.findPlatform() (Platform.kt:211)
        at okhttp3.internal.platform.Platform okhttp3.internal.platform.Platform$Companion.access$findPlatform(okhttp3.internal.platform.Platform$Companion) (Platform.kt:179)
        at void okhttp3.internal.platform.Platform.<clinit>() (Platform.kt:180)
        at void okhttp3.OkHttpClient.<init>(okhttp3.OkHttpClient$Builder) (OkHttpClient.kt:219)
        at void okhttp3.OkHttpClient.<init>() (OkHttpClient.kt:211)
        at void com.example.swiftpinx.Activity.AddMediaActivity.onClick(android.view.View) (AddMediaActivity.java:207)
        at boolean android.view.View.performClick() (View.java:5637)
        at void android.view.View$PerformClick.run() (View.java:22429)
        at void android.os.Handler.handleCallback(android.os.Message) (Handler.java:751)
        at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:95)
        at void android.os.Looper.loop() (Looper.java:154)
        at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6119)
        at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2)
        at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:886)
        at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:776)

Và cố gắng tìm một giải pháp trực tuyến để khắc phục vấn đề này và chưa có gì giải quyết được tình huống của tôi.

có lẽ bạn có thể cần mã nguồn của tôi ở đây:

package com.example.swiftpinx.Activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.Manifest;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.example.swiftpinx.Adapters.AddMediaAdapter;
import com.example.swiftpinx.Link.UrlLink;
import com.example.swiftpinx.R;

import org.jetbrains.annotations.NotNull;

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

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class AddMediaActivity extends AppCompatActivity implements
        LoaderManager.LoaderCallbacks<Cursor>, AddMediaAdapter.OnClickThumbnail,
        View.OnClickListener {

    /*
        Set up's
     */

    private static final String TAG = "AddMediaActivity";

    private final static int READ_EXTERNAL_STORAGE_REQUEST_CODE = 0;
    private final static int MEDIASTORE_LOADER_ID = 0;

    AddMediaAdapter addMediaAdapter;

    Uri imagePath;

    /*
        Pallete
     */

    RecyclerView rvGallery;

    ImageView ivImage;

    LinearLayout llPostEvent;

    Button btnPost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_media);

        rvGallery = (RecyclerView) findViewById(R.id.rvGallery);
        rvGallery.setLayoutManager(new GridLayoutManager(this, 3));

        addMediaAdapter = new AddMediaAdapter(this);

        rvGallery.setAdapter(addMediaAdapter);

        ivImage = (ImageView) findViewById(R.id.ivImage);

        llPostEvent = (LinearLayout) findViewById(R.id.llPostEvent);

        btnPost = (Button) findViewById(R.id.btnPost);

        btnPost.setOnClickListener(this);

        llPostEvent.setVisibility(View.GONE);

        checkPermissionEnternalStorage();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch(requestCode) {
            case READ_EXTERNAL_STORAGE_REQUEST_CODE:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    LoaderManager.getInstance(this).initLoader(MEDIASTORE_LOADER_ID, null, this);
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        }
    }

    private void checkPermissionEnternalStorage() {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
                LoaderManager.getInstance(this).initLoader(MEDIASTORE_LOADER_ID, null, this);
            } else {
                if(shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    // explain here.
                    Toast.makeText(this, "Swiftpin wants to view your gallery.", Toast.LENGTH_SHORT).show();
                }

                requestPermissions(new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
                        READ_EXTERNAL_STORAGE_REQUEST_CODE);
            }
        } else {
            // load default
            LoaderManager.getInstance(this).initLoader(MEDIASTORE_LOADER_ID, null, this);
        }
    }

    @NonNull
    @Override
    public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
        String[] projection = {
                MediaStore.Files.FileColumns._ID,
                MediaStore.Files.FileColumns.DATE_ADDED,
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Files.FileColumns.MEDIA_TYPE
        };

        String condition = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
                + MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE + " OR "
                + MediaStore.Files.FileColumns.MEDIA_TYPE + "="
                + MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;

        return new CursorLoader(
                this,
                MediaStore.Files.getContentUri("external"),
                projection,
                condition,
                null,
                MediaStore.Files.FileColumns.DATE_ADDED + " DESC"
        );
    }

    @Override
    public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
        addMediaAdapter.changeCursor(data);
    }

    @Override
    public void onLoaderReset(@NonNull Loader<Cursor> loader) {
        addMediaAdapter.changeCursor(null);
    }

    @Override
    public void clickThumbnail(Uri uri) {
        imagePath = uri;
        llPostEvent.setVisibility(View.VISIBLE);
        Glide.with(this)
                .load("file://" + uri)
                .centerCrop()
                .into(ivImage);
    }

    @Override
    public void onClick(View view) {
        if(view == btnPost) {
            String fileImage = String.valueOf(imagePath);

            try {
                ByteArrayOutputStream stream  = new ByteArrayOutputStream();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.RGB_565;

                Bitmap bitmap = BitmapFactory.decodeFile(fileImage, options);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
                byte[] byteArray = stream.toByteArray();

                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("image", "image.jpg",
                                RequestBody.create(MediaType.parse("image/*jpg"), byteArray))
                        .build();

                Request request = new Request.Builder()
                        .url(UrlLink.postfeed)
                        .post(requestBody)
                        .build();

                OkHttpClient client = new OkHttpClient();

                client.newCall(request).enqueue(new Callback() {
                    @Override
                    public void onFailure(@NotNull Call call, @NotNull IOException e) {
                        call.cancel();

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.i(TAG, "run: Error post");
                            }
                        });
                    }

                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    Log.i(TAG, "run: ok -> " + response.body().toString());
                                } catch(Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                    }
                });
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Phiên bản OkHttp? Thiết bị? Điều này trông giống như một lỗi OkHttp.
Jesse Wilson

bạn đã tìm thấy giải pháp nào chưa ???
Jeeva

Câu trả lời:


21

Trong khi đọc tin nhắn thông tin, nó cho tôi một ý tưởng về điều này Conscryptvà đã thực hiện một nghiên cứu và phát hiện ra rằng tôi cần cài đặt conscryptvào gradle.app của mình

implementation 'org.conscrypt:conscrypt-android:2.2.1'

Và nó hoạt động.


23
Nếu okHttp cần conscrypt, nó nên tham khảo thư viện này thay vì buộc chúng tôi phải thêm phụ thuộc này. Điều này không nên được đánh dấu là chấp nhận. Tốt hơn nên gửi một báo cáo lỗi về repo github vuông.
kroegerama

@kroegerama cũng okhttp không cần conscrypt, đó là một phụ thuộc tùy chọn mà nó tương thích. Thông báo lỗi chắc chắn có thể được cải thiện, nhưng thư viện sẽ sử dụng triển khai mặc định của hệ thống của bạn nếu không bao gồm conscrypt và tương thích với conscrypt nếu bạn đặt nó là nhà cung cấp bảo mật đầu tiên. Xem README của okhttp để biết thêm thông tin. Bất kể, tôi đồng ý rằng đây không phải là câu trả lời được chấp nhận, bởi vì cảnh báo có thể an toàn để bỏ qua và đó là một ý tưởng tồi để thêm phụ thuộc không cần thiết vào dự án của bạn.
yuval


3

OkHttp tương thích với thư viện bảo mật Conscrypt, nhưng sử dụng nó là tùy chọn. Dấu vết ngăn xếp là đáng sợ, nhưng tôi nghĩ đó chỉ là một cảnh báo cho bạn biết rằng sự phụ thuộc Conscrypt không được tìm thấy. Trong trường hợp này, OkHttp sẽ quay trở lại triển khai TLS mặc định của nền tảng của bạn.

Từ README của OkHttp :

OkHttp sử dụng triển khai TLS tích hợp trong nền tảng của bạn. Trên nền tảng Java, OkHttp cũng hỗ trợ Conscrypt, tích hợp BoringSSL với Java. OkHttp sẽ sử dụng Conscrypt nếu đó là nhà cung cấp bảo mật đầu tiên:

Security.insertProviderAt(Conscrypt.newProvider(), 1);

Câu chuyện dài quá ngắn, nếu các yêu cầu mạng của bạn đang hoạt động, có thể an toàn để bỏ qua dấu vết ngăn xếp này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.