Skip to content
This repository was archived by the owner on Mar 16, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import net.grandcentrix.thirtyinch.rx.RxTiPresenterUtils;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.math.BigInteger;
import java.util.concurrent.TimeUnit;

import rx.Observable;
Expand Down Expand Up @@ -66,7 +68,16 @@ public void call(final Void aVoid) {
protected void onCreate() {
super.onCreate();

mText.onNext("Hello World!");
final byte[] state = getPersistentState();
if (state != null) {
mCounter = new BigInteger(state).intValue();
}

if (mCounter == 0) {
mText.onNext("Click the Button");
} else {
mText.onNext("Count: " + mCounter);
}

rxSubscriptionHelper.manageSubscription(Observable.interval(0, 1, TimeUnit.SECONDS)
.compose(RxTiPresenterUtils.<Long>deliverLatestToView(this))
Expand Down Expand Up @@ -105,6 +116,13 @@ public void call(final Integer integer) {
.subscribe());
}

@Nullable
@Override
protected byte[] onSavePersistentState() {
final byte[] bytes = BigInteger.valueOf(mCounter).toByteArray();
return bytes;
}

/**
* fake a heavy calculation
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
package net.grandcentrix.thirtyinch.sample;


import net.grandcentrix.thirtyinch.TiConfiguration;
import net.grandcentrix.thirtyinch.TiLog;
import net.grandcentrix.thirtyinch.TiPresenter;
import net.grandcentrix.thirtyinch.serialize.PresenterStateSerializer;

import android.app.Application;

Expand All @@ -28,5 +31,9 @@ public void onCreate() {

// log ThirtyInch output with logcat
TiLog.setLogger(TiLog.LOGCAT);

TiPresenter.setDefaultConfig(new TiConfiguration.Builder()
.setPresenterSerializer(new PresenterStateSerializer(this))
.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

/**
Expand Down Expand Up @@ -144,6 +145,12 @@ public Builder setDistinctUntilChangedInterceptorEnabled(final boolean enabled)
return this;
}

//TODO documentation
public Builder setPresenterSerializer(TiPresenterSerializer serializer) {
mConfig.mPresenterSerializer = serializer;
return this;
}

/**
* When set to <code>true</code> the {@link TiPresenter} will be restored when the {@link
* Activity} recreates due to a configuration changes such as the orientation change.
Expand Down Expand Up @@ -197,7 +204,6 @@ public Builder setUseStaticSaviorToRetain(final boolean enabled) {
mConfig.mUseStaticSaviorToRetain = enabled;
return this;
}

}

public static final TiConfiguration DEFAULT = new Builder().build();
Expand All @@ -206,6 +212,8 @@ public Builder setUseStaticSaviorToRetain(final boolean enabled) {

private boolean mDistinctUntilChangedInterceptorEnabled = true;

private TiPresenterSerializer mPresenterSerializer;

private boolean mRetainPresenter = true;

private boolean mUseStaticSaviorToRetain = true;
Expand All @@ -216,6 +224,11 @@ public Builder setUseStaticSaviorToRetain(final boolean enabled) {
private TiConfiguration() {
}

@Nullable
public TiPresenterSerializer getPresenterSerializer() {
return mPresenterSerializer;
}

public boolean isCallOnMainThreadInterceptorEnabled() {
return mCallOnMainThreadInterceptorEnabled;
}
Expand Down
101 changes: 99 additions & 2 deletions thirtyinch/src/main/java/net/grandcentrix/thirtyinch/TiPresenter.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;

/**
Expand Down Expand Up @@ -85,6 +90,13 @@ public enum State {

private final TiConfiguration mConfig;

private String mId;

private final ExecutorService mPersistentStateExecutorService =
Executors.newSingleThreadExecutor();

private Future<byte[]> mPersistentStateFuture;

private LinkedBlockingQueue<ViewAction<V>> mPostponedViewActions = new LinkedBlockingQueue<>();

private State mState = State.INITIALIZED;
Expand All @@ -95,11 +107,11 @@ public static void setDefaultConfig(final TiConfiguration config) {
sDefaultConfig = config;
}


public TiPresenter() {
this(sDefaultConfig);
}


/**
* Constructs a presenter with a different configuration then the default one. Change the
* default configuration with {@link #setDefaultConfig(TiConfiguration)}
Expand Down Expand Up @@ -135,7 +147,6 @@ public void onRemove() {
};
}


/**
* bind a new view to this presenter.
*
Expand Down Expand Up @@ -237,6 +248,11 @@ public final void destroy() {

// release everything, no new states will be posted
mLifecycleObservers.clear();

final TiPresenterSerializer serializer = getConfig().getPresenterSerializer();
if (serializer != null) {
serializer.free(this);
}
}

/**
Expand Down Expand Up @@ -272,6 +288,11 @@ public final void detachView() {
mView = null;
}

public void generatNewId() {
final String id = getClass().getSimpleName() + ":" + hashCode() + ":" + System.nanoTime();
setId(id);
}

/**
* @return the presenter configuration
*/
Expand All @@ -280,6 +301,13 @@ public TiConfiguration getConfig() {
return mConfig;
}

/**
* @return A unique id of this instance.
*/
public final String getId() {
return mId;
}

/**
* @return the current lifecycle state
*/
Expand Down Expand Up @@ -315,6 +343,51 @@ public boolean isViewAttached() {
return mState == State.VIEW_ATTACHED;
}

//TODO documentation
public void persistState() {
mPersistentStateExecutorService.submit(new Runnable() {
@Override
public void run() {
TiPresenterSerializer serializer = mConfig.getPresenterSerializer();
if (serializer != null) {
final byte[] data = onSavePersistentState();
serializer.serialize(TiPresenter.this, data);
}
}
});
}

@NonNull
public Future<byte[]> prefetchPersistentState() {
mPersistentStateFuture = mPersistentStateExecutorService.submit(new Callable<byte[]>() {
@Override
public byte[] call() throws Exception {
final TiPresenterSerializer serializer = mConfig.getPresenterSerializer();
if (serializer != null) {
return serializer.deserialize(TiPresenter.this);
}
return null;
}
});

return mPersistentStateFuture;
}

/**
* the id can only be set once
*/
public void setId(@NonNull final String id) {
//noinspection ConstantConditions
if (id == null) {
throw new IllegalArgumentException("the id cannot be null");
}
if (mId == null) {
mId = id;
} else {
throw new IllegalArgumentException("the id can only be set once");
}
}

@Override
public String toString() {
final String viewName;
Expand All @@ -329,6 +402,24 @@ public String toString() {
+ "{view = " + viewName + "}";
}

//TODO documentation
@Nullable
protected byte[] getPersistentState() {
Future<byte[]> future = mPersistentStateFuture;
if (future == null) {
future = mPersistentStateFuture = prefetchPersistentState();
}
try {
// wait for result even when not prefetched
return future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}

/**
* Gives access to the postponed actions while the view is not attached.
*
Expand Down Expand Up @@ -400,6 +491,12 @@ protected void onDetachView() {
mCalled = true;
}

//TODO documentation
@Nullable
protected byte[] onSavePersistentState() {
return null;
}

/**
* @deprecated use {@link #onDetachView()} instead
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2016 grandcentrix GmbH
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.grandcentrix.thirtyinch;

import android.support.annotation.NonNull;

public interface TiPresenterSerializer {

@NonNull
byte[] deserialize(@NonNull TiPresenter presenter);

void free(@NonNull TiPresenter presenter);

void serialize(@NonNull final TiPresenter presenter, final byte[] data);
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public TiPresenter recover(final String id) {
}

public String safe(@NonNull final TiPresenter presenter) {
final String id = generateId(presenter);
final String id = presenter.getId();
TiLog.v(TAG, "safe presenter with id " + id + " " + presenter);
mPresenters.put(id, presenter);
return id;
Expand All @@ -62,10 +62,4 @@ public String safe(@NonNull final TiPresenter presenter) {
void clear() {
mPresenters.clear();
}

private String generateId(@NonNull final TiPresenter presenter) {
return presenter.getClass().getSimpleName()
+ ":" + presenter.hashCode()
+ ":" + System.nanoTime();
}
}
Loading