Ablehnen einer erneuten Initialisierung für eine zuvor fehlgeschlagene Klasse in OkHttp

22

Ich versuche, ein Bild mithilfe des Flask-Backends auf meinen Server hochzuladen, das die zu speichernde Datei in einem Ordner und OkHttp in Android verarbeitet. aber ich bekomme diesen Fehler in 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)

Und versuchen, online eine Lösung zu finden, um dieses Problem zu beheben, und dennoch nichts in meiner Situation zu lösen.

Vielleicht brauchen Sie meinen Quellcode hier:

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();
            }
        }
    }
}
Kim Nicole Sabordo
quelle
OkHttp Version? Gerät? Dies sieht aus wie ein OkHttp-Fehler.
Jesse Wilson
Hast du eine Lösung gefunden?
Jeeva

Antworten:

21

Beim Lesen der Info-Nachricht habe ich eine Vorstellung davon Conscryptund habe conscryptnachgeforscht und herausgefunden, dass ich auf meiner gradle.app installieren muss

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

und es funktioniert.

Kim Nicole Sabordo
quelle
23
Wenn okHttp benötigt wird conscrypt, sollte es auf diese Bibliothek verweisen, anstatt uns zu zwingen, diese Abhängigkeit hinzuzufügen. Dies sollte nicht als akzeptiert markiert werden. Besser einen Fehlerbericht über das Github-Repo von Square einreichen.
Kroegerama
@kroegerama gut okhttp nicht brauchen conscrypt, es ist eine optionale Abhängigkeit , dass es kompatibel mit. Die Fehlermeldung kann definitiv verbessert werden, aber die Bibliothek verwendet die Standardimplementierung Ihres Systems, wenn die Verschlüsselung nicht enthalten ist, und ist mit der Verschlüsselung kompatibel, wenn Sie sie explizit als ersten Sicherheitsanbieter festlegen. Weitere Informationen finden Sie in der README-Datei von okhttp. Unabhängig davon stimme ich zu, dass dies nicht die akzeptierte Antwort sein sollte, da die Warnung wahrscheinlich ignoriert werden kann und es eine schlechte Idee ist, Ihrem Projekt unnötig Abhängigkeiten hinzuzufügen.
Yuval
3

OkHttp ist mit der Conscrypt-Sicherheitsbibliothek kompatibel, die Verwendung ist jedoch optional. Die Stapelverfolgung ist beängstigend, aber ich denke, es ist nur eine Warnung, die Ihnen sagt, dass die Conscrypt-Abhängigkeit nicht gefunden wurde. In diesem Fall sollte OkHttp auf die Standard-TLS-Implementierung Ihrer Plattform zurückgreifen.

Aus OkHttps README :

OkHttp verwendet die integrierte TLS-Implementierung Ihrer Plattform. Auf Java-Plattformen unterstützt OkHttp auch Conscrypt, das BoringSSL in Java integriert. OkHttp verwendet Conscrypt, wenn es der erste Sicherheitsanbieter ist:

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

Kurz gesagt, wenn Ihre Netzwerkanforderungen funktionieren, ist es wahrscheinlich sicher, diesen Stack-Trace zu ignorieren.

Yuval
quelle