ソースを参照

修复: 释放资源时,可能出现未释放完全的问题

Caijinglong 6 年 前
コミット
f414c1ddd6

+ 9 - 0
android/src/main/java/top/kikt/ijkplayer/Ijk.kt

@@ -32,11 +32,16 @@ class Ijk(private val registry: PluginRegistry.Registrar, private val options: M
 
     var degree = 0
 
+    var isDisposed = false
+
     init {
         textureMediaPlayer = TextureMediaPlayer(mediaPlayer)
         configOptions()
         textureMediaPlayer.surfaceTexture = textureEntry.surfaceTexture()
         methodChannel.setMethodCallHandler { call, result ->
+            if (isDisposed) {
+                return@setMethodCallHandler
+            }
             when (call?.method) {
                 "setNetworkDataSource" -> {
                     val uri = call.argument<String>("uri")
@@ -264,6 +269,10 @@ class Ijk(private val registry: PluginRegistry.Registrar, private val options: M
     }
 
     fun dispose() {
+        if (isDisposed) {
+            return
+        }
+        isDisposed = true
         tryCatchError {
             notifyChannel.dispose()
             methodChannel.setMethodCallHandler(null)

+ 0 - 1
android/src/main/java/top/kikt/ijkplayer/IjkplayerPlugin.kt

@@ -16,7 +16,6 @@ import tv.danmaku.ijk.media.player.IjkMediaPlayer
  */
 class IjkplayerPlugin(private val registrar: Registrar) : MethodCallHandler {
 
-
     override fun onMethodCall(call: MethodCall, result: Result) {
         IjkMediaPlayer.loadLibrariesOnce(null)
         IjkMediaPlayer.native_profileBegin("libijkplayer.so")

+ 1 - 2
example/lib/page/error_url.dart

@@ -1,5 +1,3 @@
-import 'dart:async';
-
 import 'package:flutter/material.dart';
 import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
 import 'package:ijkplayer_example/const/video_datasource.dart';
@@ -13,6 +11,7 @@ class ErrorUrlPage extends StatefulWidget {
 class _ErrorUrlPageState extends State<ErrorUrlPage> {
   TextEditingController editingController = TextEditingController();
   IjkMediaController mediaController = IjkMediaController();
+
   // StreamSubscription statusSub;
   // StreamSubscription ijkErrorSub;
   @override

+ 2 - 0
ios/Classes/CoolFlutterIJK.h

@@ -13,6 +13,8 @@
 
 @property(nonatomic, strong) NSArray<CoolIjkOption*> *options;
 
+@property(nonatomic, assign) BOOL isDisposed;
+
 - (instancetype)initWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar;
 
 + (instancetype)ijkWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar;

+ 8 - 0
ios/Classes/CoolFlutterIJK.m

@@ -35,6 +35,7 @@
         [channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
             [weakSelf handleMethodCall:call result:result];
         }];
+        self.isDisposed = NO;
     }
 
     return self;
@@ -42,6 +43,10 @@
 
 
 - (void)dispose {
+    if(self.isDisposed){
+        return;
+    }
+    self.isDisposed = YES;
     [notifyChannel dispose];
     [[self.registrar textures] unregisterTexture:self.id];
     [controller stop];
@@ -52,6 +57,9 @@
 }
 
 - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
+    if(self.isDisposed){
+        return;
+    }
     if ([@"play" isEqualToString:call.method]) {
         [self play];
         result(@(YES));

+ 5 - 0
lib/src/controller/ijk_event_channel.dart

@@ -13,12 +13,17 @@ class _IJKEventChannel {
 
   Completer _prepareCompleter;
 
+  bool _isDisposed = false;
+
+  bool get isDisposed => _isDisposed;
+
   Future<void> init() async {
     channel = MethodChannel(channelName);
     channel.setMethodCallHandler(handler);
   }
 
   void dispose() {
+    _isDisposed = true;
     channel.setMethodCallHandler(null);
     controller = null;
   }

+ 42 - 1
lib/src/controller/plugin.dart

@@ -27,26 +27,46 @@ class _IjkPlugin {
   /// texture id
   int textureId;
 
+  bool _isDisposed;
+
+  bool get isDisposed => _isDisposed;
+
   _IjkPlugin(this.textureId);
 
   Future<void> dispose() async {
+    if (isDisposed) {
+      return;
+    }
+    _isDisposed = true;
     await _globalChannel.invokeMethod("dispose", {"id": textureId});
   }
 
   Future<void> play() async {
+    if (isDisposed) {
+      return;
+    }
     await channel.invokeMethod("play");
   }
 
   Future<void> pause() async {
+    if (isDisposed) {
+      return;
+    }
     await channel.invokeMethod("pause");
   }
 
   Future<void> stop() async {
+    if (isDisposed) {
+      return;
+    }
     await channel.invokeMethod("stop");
   }
 
   Future<void> setNetworkDataSource(
       {String uri, Map<String, String> headers = const {}}) async {
+    if (isDisposed) {
+      return;
+    }
     LogUtils.debug("id = $textureId net uri = $uri ,headers = $headers");
     await channel.invokeMethod("setNetworkDataSource", <String, dynamic>{
       "uri": uri,
@@ -55,6 +75,9 @@ class _IjkPlugin {
   }
 
   Future<void> setAssetDataSource(String name, String package) async {
+    if (isDisposed) {
+      return;
+    }
     LogUtils.debug("id = $textureId asset name = $name package = $package");
     var params = <String, dynamic>{
       "name": name,
@@ -66,8 +89,11 @@ class _IjkPlugin {
   }
 
   Future<void> setFileDataSource(String path) async {
+    if (isDisposed) {
+      return;
+    }
     if (!File(path).existsSync()) {
-      return Error.fileNotExists;
+      return;
     }
     await channel.invokeMethod("setFileDataSource", <String, dynamic>{
       "path": path,
@@ -76,6 +102,9 @@ class _IjkPlugin {
   }
 
   Future<Map<String, dynamic>> getInfo() async {
+    if (isDisposed) {
+      return null;
+    }
     try {
       var map = await channel.invokeMethod("getInfo");
       if (map == null) {
@@ -89,6 +118,9 @@ class _IjkPlugin {
   }
 
   Future<void> seekTo(double target) async {
+    if (isDisposed) {
+      return null;
+    }
     await channel.invokeMethod("seekTo", <String, dynamic>{
       "target": target,
     });
@@ -96,12 +128,18 @@ class _IjkPlugin {
 
   ///
   Future<void> setVolume(int volume) async {
+    if (isDisposed) {
+      return null;
+    }
     await channel.invokeMethod("setVolume", <String, dynamic>{
       "volume": volume,
     });
   }
 
   Future<Uint8List> screenShot() async {
+    if (isDisposed) {
+      return null;
+    }
     var result = await channel.invokeMethod("screenShot");
     if (result == null) {
       return null;
@@ -110,6 +148,9 @@ class _IjkPlugin {
   }
 
   Future<void> setSpeed(double speed) async {
+    if (isDisposed) {
+      return null;
+    }
     await channel.invokeMethod("setSpeed", speed);
   }
 }