java .lang.NoSuchMethodError: Нет виртуального метода setDataSource (Landroid / content / res / AssetFileDescriptor;) V в классе Landroid / media / MediaPlayer ОШИБКА - PullRequest
0 голосов
/ 15 января 2020

Я хочу воспроизвести видео с использованием textureview..но во время работы приложения оно останавливается, и я сталкиваюсь со следующей ошибкой. Я не знаю, что делать, я много пробовал и трачу почти 8 часов на решение этой проблемы .. но я не могу .. пожалуйста, помогите мне избавиться от этого ..

java.lang.NoSuchMethodError: No virtual method setDataSource(Landroid/content/res/AssetFileDescriptor;)V in class Landroid/media/MediaPlayer; or its super classes (declaration of 'android.media.MediaPlayer' appears in /system/framework/framework.jar)
        at com.vcube.textureview.MainActivity.onSurfaceTextureAvailable(MainActivity.java:42)
        at android.view.TextureView.getHardwareLayer(TextureView.java:370)
        at android.view.View.updateDisplayListIfDirty(View.java:14170)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.draw(View.java:15260)
        at android.widget.FrameLayout.draw(FrameLayout.java:598)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2731)
        at android.view.View.updateDisplayListIfDirty(View.java:14193)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:273)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:279)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:318)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2628)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2444)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2074)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1116)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6098)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:773)
        at android.view.Choreographer.doCallbacks(Choreographer.java:586)
        at android.view.Choreographer.doFrame(Choreographer.java:556)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:759)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:159)
        at android.app.ActivityThread.main(ActivityThread.java:5461)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)

Я включил видео в папку активов .. Я не знаю, где я не прав ..

Ниже приводится java код, который я использовал.

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.content.res.AssetFileDescriptor;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.view.Surface;
import android.view.TextureView;


import java.io.IOException;

public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {

    private TextureView textureview;
    private MediaPlayer mediaPlayer;

    private AssetFileDescriptor fileDescriptor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textureview = (TextureView) findViewById(R.id.textureView);
        textureview.setSurfaceTextureListener(this);
        mediaPlayer = new MediaPlayer();
        try {
            fileDescriptor = getAssets().openFd("random.mp4");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        Surface surfaceTexture = new Surface(surface);
        try {
            mediaPlayer.setDataSource(fileDescriptor);
            mediaPlayer.setSurface(surfaceTexture);
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mediaPlayer.start();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }

    @Override
    protected void onPause() {
        if(mediaPlayer!=null && mediaPlayer.isPlaying()){
            mediaPlayer.pause();
        }
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(mediaPlayer!=null){
            mediaPlayer.start();
        }
    }

    @Override
    protected void onDestroy() {
        if(mediaPlayer!=null){
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer =null;
        }
        super.onDestroy();
    }
}

Можете ли вы предложить мне любое решение, пожалуйста? Спасибо

1 Ответ

0 голосов
/ 16 января 2020

setDataSource(AssetFileDescriptor) был добавлен только на уровне API 24 (Android 7.0). Попытка вызвать его в более ранней версии во время выполнения приводит к тому, что cra sh выглядит следующим образом.

Аннотирование вашего метода с помощью @RequiresApi(api = Build.VERSION_CODES.N) просто подавляет «этот вызов требует API уровня 24, минимум SDK равен 15». время компиляции. Это ничего не делает во время выполнения. Из-за этого прямые вызовы получают проверки lint для уровня API 24, но, поскольку это переопределенный метод, он не вызывается напрямую каким-либо кодом и нет ошибок для вызывающих.

Что делать? Вы можете посмотреть на источник для setDataSource(AssetFileDescriptor), например, на https://cs.android.com/android/platform/superproject/+/android-9.0.0_r8: frameworks / base / media / java / android / media / MediaPlayer.java; l = 1209 и обнаружить, что вы можете достичь той же функциональности с помощью методов, доступных в более ранних версиях SDK, таких как setDataSource(FileDescriptor, long, long):

public void setDataSource(@NonNull AssetFileDescriptor afd)
        throws IOException, IllegalArgumentException, IllegalStateException {
    Preconditions.checkNotNull(afd);
    // Note: using getDeclaredLength so that our behavior is the same
    // as previous versions when the content provider is returning
    // a full file.
    if (afd.getDeclaredLength() < 0) {
        setDataSource(afd.getFileDescriptor());
    } else {
        setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
    }
}
...