web-dev-qa-db-ja.com

以前に失敗したOkHttpのクラスでの再初期化の拒否

flaskバックエンドを使用してサーバーに画像をアップロードしようとしています。これは、ファイルを処理してAndroidのOkHttpフォルダーに保存しますが、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)

そして、この問題をオンラインで解決する解決策を見つけようとしても、私の状況では何も解決しません。

多分あなたは私のソースコードが必要かもしれません、ここ:

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

情報メッセージを読んでいると、このConscryptについてのアイデアが得られ、調査を行ったところ、gradle.appにconscryptをインストールする必要があることがわかりました。

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

そしてそれは動作します。

18

OkHttpはConscryptセキュリティライブラリと互換性がありますが、使用はオプションです。スタックトレースは恐ろしいですが、Conscryptの依存関係が見つからなかったことを知らせる警告にすぎないと思います。この場合、OkHttpはプラットフォームのデフォルトのTLS実装にフォールバックする必要があります。

OkHttpのREADME から:

OkHttpは、プラットフォームの組み込みTLS実装を使用します。 Javaプラットフォームの場合OkHttpは、BoringSSLをJavaと統合するConscryptもサポートしています。OkHttpが最初のセキュリティプロバイダーである場合、Conscryptを使用します。

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

要するに、ネットワーク要求が機能している場合は、このスタックトレースを無視しても安全です。

2
yuval