diff --git a/library/build.gradle b/library/build.gradle
index 57e38f4..1e00972 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -32,6 +32,10 @@ dependencies {
implementation deps.support.annotations
implementation deps.support.fragment
+ implementation 'com.android.support:support-v4:26.1.0'
+ androidTestImplementation 'com.android.support:appcompat-v7:27.0.2'
+ androidTestImplementation 'com.android.support.constraint:constraint-layout:1.0.2'
+ androidTestAnnotationProcessor project(':compiler')
testImplementation deps.junit
androidTestImplementation deps.support.test.runner
androidTestImplementation deps.support.test.espresso
diff --git a/library/src/androidTest/AndroidManifest.xml b/library/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..3a4b393
--- /dev/null
+++ b/library/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/library/src/androidTest/java/info/dourok/esactivity/CaptureInstrumentedTest.java b/library/src/androidTest/java/info/dourok/esactivity/CaptureInstrumentedTest.java
new file mode 100644
index 0000000..7e38615
--- /dev/null
+++ b/library/src/androidTest/java/info/dourok/esactivity/CaptureInstrumentedTest.java
@@ -0,0 +1,80 @@
+package info.dourok.esactivity;
+
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import info.dourok.esactivity.activity.CaptureTestActivity;
+import info.dourok.esactivity.test.R;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.Espresso.pressBack;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.action.ViewActions.replaceText;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static info.dourok.esactivity.util.EspressoHelper.getActivityInstance;
+import static org.hamcrest.Matchers.not;
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class CaptureInstrumentedTest {
+ @Rule
+ public ActivityTestRule mActivityRule =
+ new ActivityTestRule<>(CaptureTestActivity.class);
+
+
+ @Test
+ public void activity__ref_should_be_updated_after_activity_recreate() {
+ String id = getActivityInstance().toString();
+ onView(withText("captureActivity")).perform(click());
+
+ getInstrumentation().runOnMainSync(() -> mActivityRule.getActivity().recreate());
+
+ pressBack();
+ String idNew = getActivityInstance().toString();
+ onView(withId(R.id.content)).check(matches(not(withText(id))));
+ onView(withId(R.id.content)).check(matches(withText(idNew)));
+ }
+
+ @Test
+ public void view_with_id__ref_should_be_updated_after_activity_recreate() {
+ final String text = "text";
+ onView(withText("captureView")).perform(click());
+
+ getInstrumentation().runOnMainSync(() -> mActivityRule.getActivity().recreate());
+
+ onView(withId(R.id.edit_text)).perform(replaceText(text));
+ onView(withId(R.id.action_ok)).perform(click());
+ onView(withId(R.id.content)).check(matches(withText(text)));
+ }
+
+ @Test
+ public void fragment_with_id__ref_should_be_updated_after_activity_recreate(){
+ final String text = "text";
+ onView(withText("captureFragment")).perform(click());
+
+ getInstrumentation().runOnMainSync(() -> mActivityRule.getActivity().recreate());
+
+ onView(withId(R.id.edit_text)).perform(replaceText(text));
+ onView(withId(R.id.action_ok)).perform(click());
+ onView(withId(R.id.content)).check(matches(withText(text)));
+ }
+
+
+ @Test
+ public void method__ref_should_be_updated_after_activity_recreate() throws Exception {
+ final String text = "text";
+ onView(withText("methodRef")).perform(click());
+ getInstrumentation().runOnMainSync(() -> mActivityRule.getActivity().recreate());
+ onView(withId(R.id.edit_text)).perform(replaceText(text));
+ onView(withId(R.id.action_ok)).perform(click());
+ onView(withId(R.id.content)).check(matches(withText(text)));
+ }
+}
diff --git a/library/src/androidTest/java/info/dourok/esactivity/ExampleInstrumentedTest.java b/library/src/androidTest/java/info/dourok/esactivity/ExampleInstrumentedTest.java
deleted file mode 100644
index 5c8bc56..0000000
--- a/library/src/androidTest/java/info/dourok/esactivity/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package info.dourok.esactivity;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("info.dourok.esactivity.test", appContext.getPackageName());
- }
-}
diff --git a/library/src/androidTest/java/info/dourok/esactivity/activity/CaptureTestActivity.java b/library/src/androidTest/java/info/dourok/esactivity/activity/CaptureTestActivity.java
new file mode 100644
index 0000000..889f8b0
--- /dev/null
+++ b/library/src/androidTest/java/info/dourok/esactivity/activity/CaptureTestActivity.java
@@ -0,0 +1,39 @@
+package info.dourok.esactivity.activity;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import android.view.View;
+import android.widget.TextView;
+import info.dourok.esactivity.BuilderUtil;
+import info.dourok.esactivity.test.R;
+
+public class CaptureTestActivity extends AppCompatActivity {
+
+ private TextView textView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_test);
+ textView = findViewById(R.id.content);
+ }
+
+ public void captureActivity(View v) {
+ EditorActivityBuilder.create(this).forCancel(intent -> showContent(this.toString())).start();
+ }
+
+ public void captureView(View v) {
+ TextView localTextView = findViewById(R.id.content);
+ EditorActivityBuilder.create(this).forContent(localTextView::setText).start();
+ }
+
+ public void methodRef(View v) {
+
+ EditorActivityBuilder.create(this).forContent(this::showContent).start();
+ }
+
+ void showContent(String s) {
+ textView.setText(s);
+ }
+}
diff --git a/library/src/androidTest/java/info/dourok/esactivity/activity/EditorActivity.java b/library/src/androidTest/java/info/dourok/esactivity/activity/EditorActivity.java
new file mode 100644
index 0000000..b14b060
--- /dev/null
+++ b/library/src/androidTest/java/info/dourok/esactivity/activity/EditorActivity.java
@@ -0,0 +1,56 @@
+package info.dourok.esactivity.activity;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.EditText;
+import info.dourok.esactivity.Builder;
+import info.dourok.esactivity.BuilderParameter;
+import info.dourok.esactivity.BuilderUtil;
+import info.dourok.esactivity.Result;
+import info.dourok.esactivity.ResultParameter;
+import info.dourok.esactivity.test.R;
+
+/** @author tiaolins */
+@Builder
+@Result(
+ name = "content",
+ parameters = {@ResultParameter(name = "content", type = String.class)}
+)
+public class EditorActivity extends AppCompatActivity {
+ @BuilderParameter String hint;
+ EditorActivityHelper mHelper;
+ private EditText editText;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_editor);
+ mHelper = BuilderUtil.createHelper(this);
+ editText = findViewById(R.id.edit_text);
+ if (hint != null) {
+ editText.setHint(hint);
+ }
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_editor, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ case R.id.action_ok:
+ mHelper.finishContent(editText.getText().toString());
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/library/src/androidTest/java/info/dourok/esactivity/activity/OneButtonFragment.java b/library/src/androidTest/java/info/dourok/esactivity/activity/OneButtonFragment.java
new file mode 100644
index 0000000..f81b6b4
--- /dev/null
+++ b/library/src/androidTest/java/info/dourok/esactivity/activity/OneButtonFragment.java
@@ -0,0 +1,59 @@
+package info.dourok.esactivity.activity;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+/** A simple {@link Fragment} subclass. */
+public class OneButtonFragment extends Fragment {
+
+ CaptureTestActivity activity;
+
+ public OneButtonFragment() {
+ // Required empty public constructor
+ }
+
+ /**
+ * Use this factory method to create a new instance of this fragment using the provided
+ * parameters.
+ */
+ public static OneButtonFragment newInstance() {
+ return new OneButtonFragment();
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ Button btn = new Button(getActivity());
+ btn.setText("captureFragment");
+ btn.setOnClickListener(
+ v -> EditorActivityBuilder.create(activity).forContent(activity::showContent).start());
+ return btn;
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ if (context instanceof CaptureTestActivity) {
+ activity = (CaptureTestActivity) context;
+ } else {
+ throw new RuntimeException(context.toString() + " must implement CaptureTestActivity");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ activity = null;
+ }
+}
diff --git a/library/src/androidTest/java/info/dourok/esactivity/util/EspressoHelper.java b/library/src/androidTest/java/info/dourok/esactivity/util/EspressoHelper.java
new file mode 100644
index 0000000..6fa87b5
--- /dev/null
+++ b/library/src/androidTest/java/info/dourok/esactivity/util/EspressoHelper.java
@@ -0,0 +1,33 @@
+package info.dourok.esactivity.util;
+
+import android.app.Activity;
+import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
+import info.dourok.esactivity.function.Consumer;
+import java.util.Collection;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.support.test.runner.lifecycle.Stage.RESUMED;
+
+/**
+ * @author tiaolins
+ * @date 2018/3/2.
+ */
+public class EspressoHelper {
+ private EspressoHelper() {}
+
+ private static Activity currentActivity;
+
+ public static synchronized Activity getActivityInstance() {
+ getInstrumentation()
+ .runOnMainSync(
+ () -> {
+ Collection resumedActivities =
+ ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(RESUMED);
+ if (resumedActivities.iterator().hasNext()) {
+ currentActivity = resumedActivities.iterator().next();
+ }
+ });
+
+ return currentActivity;
+ }
+}
diff --git a/library/src/androidTest/java/info/dourok/esactivity/util/OrientationChangeAction.java b/library/src/androidTest/java/info/dourok/esactivity/util/OrientationChangeAction.java
new file mode 100644
index 0000000..e569eed
--- /dev/null
+++ b/library/src/androidTest/java/info/dourok/esactivity/util/OrientationChangeAction.java
@@ -0,0 +1,99 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - Nathan Barraille
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+package info.dourok.esactivity.util;
+
+import android.app.Activity;
+import android.content.pm.ActivityInfo;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
+import android.support.test.runner.lifecycle.Stage;
+import android.view.View;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import org.hamcrest.Matcher;
+
+import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
+
+/** An Espresso ViewAction that changes the orientation of the screen */
+public class OrientationChangeAction implements ViewAction {
+ private final int orientation;
+
+ private OrientationChangeAction(int orientation) {
+ this.orientation = orientation;
+ }
+
+ @Override
+ public Matcher getConstraints() {
+ return isRoot();
+ }
+
+ @Override
+ public String getDescription() {
+ return "change orientation to " + orientation;
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ uiController.loopMainThreadUntilIdle();
+ final Activity activity = getActivity(view);
+ activity.setRequestedOrientation(orientation);
+
+ Collection resumedActivities =
+ ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
+ if (resumedActivities.isEmpty()) {
+ throw new RuntimeException("Could not change orientation");
+ }
+ }
+
+ private static Activity getActivity(View view) {
+ Activity activity = null;
+ if (view.getContext()
+ .getClass()
+ .getName()
+ .contains("com.android.internal.policy.DecorContext")) {
+ try {
+ Field field = view.getContext().getClass().getDeclaredField("mPhoneWindow");
+ field.setAccessible(true);
+ Object obj = field.get(view.getContext());
+ java.lang.reflect.Method m1 = obj.getClass().getMethod("getContext");
+ activity = (Activity) (m1.invoke(obj));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ activity = (Activity) view.getContext();
+ }
+ return activity;
+ }
+
+ public static ViewAction orientationLandscape() {
+ return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ }
+
+ public static ViewAction orientationPortrait() {
+ return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ }
+}
diff --git a/library/src/androidTest/res/layout/activity_editor.xml b/library/src/androidTest/res/layout/activity_editor.xml
new file mode 100644
index 0000000..685ca4d
--- /dev/null
+++ b/library/src/androidTest/res/layout/activity_editor.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/library/src/androidTest/res/layout/activity_test.xml b/library/src/androidTest/res/layout/activity_test.xml
new file mode 100644
index 0000000..a1f6706
--- /dev/null
+++ b/library/src/androidTest/res/layout/activity_test.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
diff --git a/library/src/androidTest/res/menu/menu_editor.xml b/library/src/androidTest/res/menu/menu_editor.xml
new file mode 100644
index 0000000..c6f4021
--- /dev/null
+++ b/library/src/androidTest/res/menu/menu_editor.xml
@@ -0,0 +1,10 @@
+
diff --git a/library/src/androidTest/res/values/strings.xml b/library/src/androidTest/res/values/strings.xml
new file mode 100644
index 0000000..01a5d47
--- /dev/null
+++ b/library/src/androidTest/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ library
+ OK
+
diff --git a/library/src/androidTest/res/values/styles.xml b/library/src/androidTest/res/values/styles.xml
new file mode 100644
index 0000000..ee421b5
--- /dev/null
+++ b/library/src/androidTest/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file