Rxjava memory leak resolution in Android and Rxjava package

Source: Internet
Author: User
Tags log log

This article transferred from: HTTP://BLOG.CSDN.NET/ADZCSX2
Rxjava is now a very avant-garde asynchronous framework, but also because he is very new, so it is more difficult to navigate.
Just like Okhttp calls its Cancel method directly in OnStop or OnDestroy, but Rxjava is not that simple.

Because if each request get observable object, and then OnStop in unsubscribe Cancel, this is not conducive to encapsulation. And it will cause a lot of code, so I found a solution with rxlifecycle.
Pilot Pack

    ‘com.trello:rxlifecycle:0.5.0‘    ‘com.trello:rxlifecycle-components:0.5.0‘

Then write rxactivity, the original author GitHub on the source code, I based on my own situation slightly modified a bit.

ImportAndroid.os.Bundle;ImportAndroid.support.annotation.CallSuper;ImportAndroid.support.annotation.NonNull;Importandroid.support.v4.app.FragmentActivity;ImportCom.trello.rxlifecycle.ActivityEvent;ImportCom.trello.rxlifecycle.ActivityLifecycleProvider;ImportCom.trello.rxlifecycle.RxLifecycle;ImportRx. Observable;ImportRx.subjects.BehaviorSubject;/** * Created by a on 2016/5/6. * * Public  class rxactivity extends fragmentactivity  implements  Activitylifecycleprovider {     Public Finalbehaviorsubject<activityevent> lifecyclesubject = Behaviorsubject.create ();@NonNull    @Override     PublicObservable<activityevent>Lifecycle() {returnLifecyclesubject.asobservable (); }@NonNull    @Override     Public<T> Observable.transformer<t, t>binduntilevent(@NonNull activityevent event) {returnRxlifecycle.binduntilevent (Lifecyclesubject, event); }@NonNull    @Override     Public<T> Observable.transformer<t, t>bindtolifecycle() {returnRxlifecycle.bindactivity (Lifecyclesubject); }@Override    @CallSuper    protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);    Lifecyclesubject.onnext (activityevent.create); }@Override    @CallSuper    protected void OnStart() {Super. OnStart ();    Lifecyclesubject.onnext (Activityevent.start); }@Override    @CallSuper    protected void Onresume() {Super. Onresume ();    Lifecyclesubject.onnext (Activityevent.resume); }@Override    @CallSuper    protected void OnPause() {lifecyclesubject.onnext (activityevent.pause);Super. OnPause (); }@Override    @CallSuper    protected void OnStop() {lifecyclesubject.onnext (activityevent.stop);Super. OnStop (); }@Override    @CallSuper    protected void OnDestroy() {lifecyclesubject.onnext (Activityevent.destroy);Super. OnDestroy (); }}

Inherit the rxactivity with your own activity. Add a place to the network request
. Compose (Rxlifecycle.binduntilevent (Lifecycle (), activityevent.stop))
This means canceling the request at the stop cycle.

I used the previous blog upload Image example, now is mainactivity into secondactivity, click the button after uploading a picture, and then get the results returned.

File File =NewFile (environment.getexternalstoragedirectory () +"/123.png"); Httputil.getiimagepp (). Uploadimage ("C1a2b3ab56a2f218aed9b2ab3c16ce88","be8318b73cef1c2bcafb6c8a77922436", Httputil.postfileparams ("img", file))//encapsulates the main thread subscribe running in a sub-thread, the following will tell how to encapsulate. . Compose (Rxhelper.io_main (secondactivity. This))//.compose (Rxlifecycle.binduntilevent (Lifecycle (), activityevent.stop)). Subscribe (NewRxsubscriber<object> () {@Override                     Public void _onnext(Object o) {L.E ("AAAA");                    Tv.settext (String) o); }@Override                     Public void _OnError(String msg) {                    }                });

Without adding. Compose (rxlifecycle.binduntilevent (Lifecycle (), activityevent.stop), click the button to upload and immediately return to the log log of the previous activity:

After returning to Mainactivity, about 2 seconds later, this sentence appears.

05-0618:37:58.59015642-15642/com.sanniuben.myapplication E/way: aaaa

After the addition, there was no return.

It can be seen that he canceled the request at the time of OnStop.

Rxlifecycle github:https://github.com/trello/rxlifecycle
Rxfragment Source page
Https://github.com/trello/RxLifecycle/tree/master/rxlifecycle-components/src/main/java/com/trello/rxlifecycle/components

The fragment operation is similar to this. Just need to inherit rxfragment

Next is the encapsulation.

 Public classrxhelper<t> {//Sub-thread run, main thread callback    //Note that this cannot be set to static, and the generics cannot be used after being set to static. That's why I subcribe the generics only for object reasons, and now blogs have been updated.      PublicObservable.transformer<t, t>Io_main(Final rxactivity context) {return NewObservable.transformer<t, t> () {@Override PublicObservable<t>Pager(observable<t> tobservable) {observable<t> TObservable1 = (observable<t>) tobservable. Subscribeon ( Schedulers.io ()). Doonsubscribe (NewAction0 () {@Override Public void Pager() {A weak reference is implemented in the//progressdialogutil.showprogress and does not cause a memory leak. Progressdialogutil.showprogress (Context,"Loading, please wait"); }}). Subscribeon (Androidschedulers.mainthread ()). OB Serveon (Androidschedulers.mainthread ()). Compose (Rxlifecycle.binduntilevent (Context.lifecycle (), Ac Tivityevent.stop));returnTObservable1;    }        }; }}

Subscriber

/** * Created by a on 2016/5/6. * * Public Abstract classRxsubscriber<t> extends subscriber<t>{@Override Public void oncompleted() {//Cancel the dialog box when finishedProgressdialogutil.dismiss (); } @Override Public void OnError(Throwable e)        {E.printstacktrace (); _OnError (E.getmessage ());if(! Netutils.isconnected (Myapplication.getcontextobject ())) {Toast.maketext (Myapplication.getcontextobject ()),"The request failed, please check the network!", Toast.length_short). Show (); Progressdialogutil.dismiss ();return; }} @Override Public void OnNext(T T)    {_onnext (t); } Public Abstract void_OnNext(T T); Public Abstract void_OnError(String msg);}

Now take a look at the new request

File File =NewFile (environment.getexternalstoragedirectory () +"/123.png"); Httputil.getiimagepp (). Uploadimage ("C1a2b3ab56a2f218aed9b2ab3c16ce88","be8318b73cef1c2bcafb6c8a77922436", Httputil.postfileparams ("img", file))//Just add this sentence,rxhelper<t> generic content needs to be entered by itself. Compose (NewRxhelper<string>.io_main (secondactivity. This))//Here is new's our own Rxsubscriber. Subscribe (NewRxsubscriber<string> () {@Override                     Public void _onnext(String o) {L.E ("AAAA");                    Tv.settext (o); }@Override                     Public void _OnError(String msg) {                    }                });

This completes the encapsulation of the Rxjava. Now, every time you access the network, the dialog box is displayed, and the cancel dialog is requested, and the request is canceled at the activity lifecycle stop.

Transformer is actually a func1< observable< T, observable< r>> In other words: it is possible to convert one type of observable into another type of observable, and the invocation of a series of inline operators is identical.

The difference between compose and Flatmap ():

What is about FlatMap ()?

1. At the wondering, the difference is between using compose () and FlatMap (). They both emit Observable, which means both can reuse a series of operators, right?
The difference is this compose () is a higher level abstraction:it operates on the entire stream, not individually emitted Items. In more specific terms:

2, Compose () is the only-to-get-original Observable from the stream. Therefore, operators that affect the whole stream (like Subscribeon () and Observeon ()) need to use compose ().
In contrast, if you put Subscribeon ()/observeon () on FlatMap (), it would only affect the Observable you create in FlatMap ( ) but not the rest of the stream.

3, compose () executes immediately when you create the Observable stream, as if you had written the operators inline. FlatMap () executes when its onNext () are called, each time it is called. In other words, FLATMAP () transforms each item, whereas compose () transforms the whole stream.
FlatMap () is necessarily less efficient because it have to create a new Observable every time OnNext () is called. Compose () operates on the stream as it is.

If you want to replace some operators with reusable code, use compose (). FlatMap () has many uses and this is not one of the them.

Referenced from: http://blog.danlew.net/2015/03/02/dont-break-the-chain/

To put it simply:
1, compose is affecting the entire stream, and Flatmap is only the part that affects its own transformation.
2. Flatmap is executed after calling next (), while compose is executed directly.
3, Flatmap in next () after the execution will create a observable object (for the next operation to form a chain structure), and compose more like stitching to the top of the stream, a one-time execution, so the relative compose efficiency a bit higher.

This article is code: http://download.csdn.net/detail/jdsjlzx/9529124

Rxjava memory leak resolution in Android and Rxjava package

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.