hendrik hendrikson
hendrik hendrikson

Reputation: 31

Flutter Event Channel Stream causes crash of app (Lost connection to device)

I was following along a tutorial described in this article.
The code of the article can be found here: https://github.com/seamusv/event_channel_sample.
I basically do the same only that i use kotlin instead of java.

In native code (MainActivity.kt):

class MainActivity: FlutterActivity() {
  private val STREAM_TAG = "alarm.eventchannel.sample/stream";

  private var timerSubscription : Disposable? = null

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    GeneratedPluginRegistrant.registerWith(this)

    EventChannel(getFlutterView(), STREAM_TAG).setStreamHandler(
      object : EventChannel.StreamHandler {
        override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
          Log.w("TAG", "adding listener")
          [email protected] = Observable.interval(0, 1, TimeUnit.SECONDS)
             .subscribe (
               {  
                 Log.w("Test", "Result we just received: $it");
                 events.success(1);
               }, // OnSuccess
               { error -> events.error("STREAM", "Error in processing observable", error); }, // OnError
               { println("Complete"); } // OnCompletion
             )
        }

        override fun onCancel(arguments: Any?) {
          Log.w("TAG", "adding listener")
          if ([email protected] != null) {
            [email protected]?.dispose()
            [email protected] = null
          }
        }
      }
    )

  }
}

In my main.dart i do the following:

int _timer = 0;
  StreamSubscription _timerSubscription = null;

void _enableTimer() {
  if (_timerSubscription == null) {
    _timerSubscription = stream.receiveBroadcastStream().listen(_updateTimer);
  }
}

void _disableTimer() {
  if (_timerSubscription != null) {
    _timerSubscription.cancel();
    _timerSubscription = null;
  }
}

void _updateTimer(timer) {
  debugPrint("Timer $timer");
  setState(() => _timer = timer);
}

In the build function i also create a button which then calls _enableTimer() onPressed.

new FlatButton(
  child: const Text('Enable'),
  onPressed: _enableTimer,
)

Whenever i now press the button to call _enableTimer() the app crashes and i get the output "Lost connection to device"...
Am i doing something wrong or is this a bug in a newer version of Flutter since the article is from December 2017?

Upvotes: 2

Views: 1964

Answers (1)

hendrik hendrikson
hendrik hendrikson

Reputation: 31

The solution to my problem was basically to start the stream in the main thread:

class MainActivity: FlutterActivity() {
  private val CHANNEL = "alarm.flutter.dev/audio"

  private val STREAM_TAG = "alarm.eventchannel.sample/stream";

  private var timerSubscription : Disposable? = null

  override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    GeneratedPluginRegistrant.registerWith(flutterEngine)

    EventChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), STREAM_TAG).setStreamHandler(
      object : EventChannel.StreamHandler {
        override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
          Log.w("TAG", "adding listener")
          [email protected] = Observable
             .interval(1000, TimeUnit.MILLISECONDS)
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe (
               {  
                 Log.w("Test", "Result we just received: $it"); 
                 events.success(it);
               }, // OnSuccess
               { error -> events.error("STREAM", "Error in processing observable", error); }, // OnError
               { println("Complete"); } // OnCompletion
             )
        }

        override fun onCancel(arguments: Any?) {
          Log.w("TAG", "adding listener")
          if ([email protected] != null) {
            [email protected]?.dispose()
            [email protected] = null
          }
        }
      }
    )

  }

Upvotes: 1

Related Questions