public class IdentityParcelable implements Parcelable { private final ReferenceBinder referenceBinder = new ReferenceBinder(); public final Object content; public static final Parcelable.Creator<IdentityParcelable> CREATOR = new Creator<IdentityParcelable>() { @Override public IdentityParcelable createFromParcel(Parcel source) { try { return ((ReferenceBinder) source.readStrongBinder()).get(); } catch (ClassCastException e) { // It must be application recover from crash. return null; } } @Override public IdentityParcelable[] newArray(int size) { return new IdentityParcelable[size]; } }; public IdentityParcelable(Object content) { this.content = content; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeStrongBinder(referenceBinder); } private class ReferenceBinder extends Binder { IdentityParcelable get() { return IdentityParcelable.this; } } }
public class ActivityRecord { private static final Handler UI_HANDLER = new Handler(Looper.getMainLooper()); private Activity visibleActivity; private final Collection<Runnable> pendingVisibleActivityCallbacks = new LinkedList<>(); public void executeOnVisible(final Runnable callback) { UI_HANDLER.post(new Runnable() { @Override public void run() { if (visibleActivity == null) { pendingVisibleActivityCallbacks.add(callback); } else { callback.run(); } } }); } void setVisibleActivity(Activity visibleActivity) { this.visibleActivity = visibleActivity; if (visibleActivity != null) { for (Runnable callback : pendingVisibleActivityCallbacks) { callback.run(); } pendingVisibleActivityCallbacks.clear(); } } public Activity getVisibleActivity() { return visibleActivity; } }
public class BasicActivity extends Activity { private static final String ACTIVITY_RECORD_KEY = "com.zzz.ACTIVITY_RECORD_KEY"; private ActivityRecord activityRecord; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { activityRecord = new ActivityRecord(); } else { activityRecord = (ActivityRecord) ((IdentityParcelable) savedInstanceState.getParcelable(ACTIVITY_RECORD_KEY)).content; } } @Override protected void onStart() { super.onStart(); activityRecord.setVisibleActivity(this); } @Override protected void onStop() { activityRecord.setVisibleActivity(null); super.onStop(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(ACTIVITY_RECORD_KEY, new IdentityParcelable(activityRecord)); } public ActivityRecord getActivityRecord() { return activityRecord; } }
public class BackgroundTask { private final ActivityRecord activityRecord; public BackgroundTask(ActivityRecord activityRecord) { this.activityRecord = activityRecord; } public void execute() { new Thread() { @Override public void run() { doInBackground(); activityRecord.executeOnVisible(new Runnable() { @Override public void run() { onPostExecute(activityRecord.getVisibleActivity()); } }); } }.start(); } protected void publishProgress(final int progress) { activityRecord.executeOnVisible(new Runnable() { @Override public void run() { onProgressUpdate(activityRecord.getVisibleActivity(), progress); } }); } protected void doInBackground() { } protected void onProgressUpdate(Activity activity, int progress) { } protected void onPostExecute(Activity activity) { } }
public class LengthActivity extends BasicActivity { private TextView statusText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.length_activity); statusText = (TextView) findViewById(R.id.statusText); findViewById(R.id.calculateLengthButton).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new LengthTask( getActivityRecord(), ((TextView) findViewById(R.id.sampleField)).getText().toString() ).execute(); } }); } private void setCalculationResult(CharSequence sample, int length) { statusText.setText("Length of " + sample + " is " + length); } private void setCalculationProgress(CharSequence sample, int progress) { statusText.setText("Calculating length of " + sample + ". Step " + progress + " of 100."); } private static class LengthTask extends BackgroundTask { final String sample; int length; LengthTask(ActivityRecord activityRecord, String sample) { super(activityRecord); this.sample = sample; } @Override protected void doInBackground() { for (int i = 0; i < 100; i++) { publishProgress(i); try { Thread.sleep(50); } catch (InterruptedException e) { throw new IllegalStateException(e); } } length = sample.length(); } @Override protected void onProgressUpdate(Activity activity, int progress) { ((LengthActivity) activity).setCalculationProgress(sample, progress); } @Override protected void onPostExecute(Activity activity) { ((LengthActivity) activity).setCalculationResult(sample, length); } } }
public class ValueBinder extends Binder { public Object value; public ValueBinder() { } public ValueBinder(Object value) { this.value = value; } public <V> V value() { //noinspection unchecked return (V) value; } }
Source: https://habr.com/ru/post/274635/
All Articles