Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Marchuck/e2610ed577cdb6ef0f68753aec526a33 to your computer and use it in GitHub Desktop.
Save Marchuck/e2610ed577cdb6ef0f68753aec526a33 to your computer and use it in GitHub Desktop.
workaround for request with activity and screen orientation changes
/**
* @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