Created
November 15, 2016 18:50
-
-
Save Marchuck/e2610ed577cdb6ef0f68753aec526a33 to your computer and use it in GitHub Desktop.
workaround for request with activity and screen orientation changes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Lukasz Marczak | |
* @since 28.09.16. | |
*/ | |
import android.graphics.Bitmap; | |
import android.graphics.BitmapFactory; | |
import android.os.Bundle; | |
import android.support.v7.app.AppCompatActivity; | |
import android.util.Log; | |
import android.view.View; | |
import android.widget.ImageView; | |
import android.widget.ProgressBar; | |
import java.io.BufferedInputStream; | |
import java.io.IOException; | |
import java.util.concurrent.Callable; | |
import retrofit.RestAdapter; | |
import retrofit.client.Response; | |
import retrofit.http.GET; | |
import retrofit.http.Path; | |
import retrofit.mime.TypedInput; | |
import rx.Observable; | |
import rx.Subscriber; | |
import rx.android.schedulers.AndroidSchedulers; | |
import rx.schedulers.Schedulers; | |
import rx.subjects.ReplaySubject; | |
import rx.subjects.Subject; | |
import rx.subscriptions.CompositeSubscription; | |
public class OrientationChangeWithPendingNetworkRequestActivity extends AppCompatActivity { | |
public static final String TAG = OrientationChangeWithPendingNetworkRequestActivity.class.getSimpleName(); | |
Subject<Bitmap, Bitmap> pendingRequest; | |
CompositeSubscription compositeSubscription = new CompositeSubscription(); | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_base); | |
final ImageView imageView = (ImageView) findViewById(R.id.imageView); | |
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); | |
boolean isFirstRequest = isFirstRequest(); | |
pendingRequest = retrievePendingRequestOrCreateNew(); | |
if (isFirstRequest) { | |
String url = "your-url-to-large-bitmap-" + | |
"you-won't-lose-pending-request-because" + | |
"you-retain-request-inside-subject"; | |
getBitmapImpl(url).subscribe(pendingRequest); | |
} else { | |
//already subscribed, result is already inside Subject | |
//called when screen is rotated, we won't request twice | |
} | |
progressBar.setVisibility(View.VISIBLE); | |
rx.Subscription subscription = pendingRequest.observeOn(AndroidSchedulers.mainThread()) | |
.subscribe(new Subscriber<Bitmap>() { | |
@Override | |
public void onCompleted() { | |
Log.d(TAG, "onCompleted: "); | |
} | |
@Override | |
public void onError(Throwable e) { | |
Log.e(TAG, "onError: ", e); | |
} | |
@Override | |
public void onNext(Bitmap bitmap) { | |
Log.d(TAG, "onNext: "); | |
progressBar.setVisibility(View.GONE); | |
imageView.setImageBitmap(bitmap); | |
} | |
}); | |
compositeSubscription.add(subscription); | |
} | |
@Override | |
protected void onDestroy() { | |
Log.d(TAG, "onDestroy: "); | |
//not sure I should clear this | |
// if (!compositeSubscription.isUnsubscribed()) compositeSubscription.unsubscribe(); | |
super.onDestroy(); | |
} | |
@SuppressWarnings("unchecked") | |
Subject<Bitmap, Bitmap> retrievePendingRequestOrCreateNew() { | |
Object lastPendingRequest = getLastCustomNonConfigurationInstance(); | |
if (lastPendingRequest == null) { | |
return createSubject(); | |
} else { | |
return (Subject<Bitmap, Bitmap>) lastPendingRequest; | |
} | |
} | |
Subject<Bitmap, Bitmap> createSubject() { | |
return ReplaySubject.create(); | |
} | |
@Override | |
public Object onRetainCustomNonConfigurationInstance() { | |
return pendingRequest; | |
} | |
static Observable<Bitmap> getBitmapImpl(final String url) { | |
return Observable.fromCallable(new Callable<Bitmap>() { | |
@Override | |
public Bitmap call() throws Exception { | |
String[] pieces = url.split("/"); | |
String query = pieces[pieces.length - 1]; | |
String endpoint = url.replace("/" + query, ""); | |
RestAdapter adapter = new RestAdapter.Builder().setEndpoint(endpoint).build(); | |
ImagesAPI api = adapter.create(ImagesAPI.class); | |
Response blockingResponse = api.getImage(query); | |
TypedInput input = blockingResponse.getBody(); | |
Bitmap bitmap = null; | |
try { | |
BufferedInputStream stream = new BufferedInputStream(input.in()); | |
bitmap = BitmapFactory.decodeStream(stream); | |
stream.close(); | |
} catch (IOException e) { | |
Log.e(TAG, "failed to decode stream"); | |
e.printStackTrace(); | |
} | |
return bitmap; | |
} | |
}).subscribeOn(Schedulers.newThread()); | |
} | |
public interface ImagesAPI { | |
@GET("/{path}") | |
Response getImage(@Path("path") String subString); | |
} | |
boolean isFirstRequest() { | |
return getLastCustomNonConfigurationInstance() == null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment