OkHttp에서 이전에 실패한 클래스에서 다시 초기화 거부


22

플라스크 백 엔드를 사용하여 폴더에 저장하기 위해 파일을 처리하고 Android에서 OkHttp를 사용하여 서버에 이미지를 업로드하려고합니다. 하지만 안드로이드 에서이 오류가 발생합니다.

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)

그리고이 문제를 해결하기 위해 온라인으로 해결책을 찾으려고 노력했지만 여전히 내 상황에서는 해결할 수 없습니다.

어쩌면 여기에 내 소스 코드가 필요할 수 있습니다.

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

OkHttp 버전? 장치? 이것은 OkHttp 버그처럼 보입니다.
Jesse Wilson

어떤 해결책을 찾았습니까 ???
Jeeva

답변:


21

정보 메시지를 읽는 동안 나에게 이것에 대한 아이디어를 제공 Conscrypt하고 연구를하고 conscryptgradle.app 에 설치해야한다는 것을 알았습니다.

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

작동합니다.


23
okHttp가 필요한 경우 conscrypt,이 의존성을 추가하도록 강요하는 대신이 라이브러리를 참조해야합니다. 승인 된 것으로 표시해서는 안됩니다. 광장의 github 저장소에 버그 보고서를 제출하는 것이 좋습니다.
kroegerama

@kroegerama well okhttp는 암호화가 필요 하지 않으며 호환 가능한 선택적 종속성입니다. 오류 메시지는 확실히 개선 될 수 있지만 conscrypt가 포함되지 않은 경우 라이브러리는 시스템의 기본 구현을 사용하며 명시 적으로 첫 번째 보안 제공자로 설정하면 conscrypt와 호환됩니다. 자세한 내용은 okhttp의 README를 참조하십시오. 어쨌든 경고를 무시해도 안전하고 프로젝트에 종속성을 불필요하게 추가하는 것은 좋지 않기 때문에 이것이 받아 들여서는 안된다는 데 동의합니다.
yuval


3

OkHttp는 Conscrypt 보안 라이브러리와 호환되지만이를 사용하는 것은 선택 사항입니다. 스택 추적은 무섭지 만 Conscrypt 종속성을 찾을 수 없다는 경고 일뿐입니다. 이 경우 OkHttp는 플랫폼의 기본 TLS 구현으로 폴백해야합니다.

에서 OkHttp의 README :

OkHttp는 플랫폼의 내장 TLS 구현을 사용합니다. Java 플랫폼에서 OkHttp는 BoringSSL을 Java와 통합하는 Conscrypt도 지원합니다. OkHttp는 Conscrypt가 첫 번째 보안 제공 업체 인 경우 다음을 사용합니다.

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

간단히 말해 네트워크 요청이 작동하면이 스택 추적을 무시하는 것이 안전 할 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.