Skip to content
This repository has been archived by the owner on Aug 9, 2020. It is now read-only.

Commit

Permalink
provide a safety instance of the Activity/Fragment to stay sync with …
Browse files Browse the repository at this point in the history
…the most recent instance
  • Loading branch information
Victor committed Mar 16, 2016
1 parent 9c37211 commit 3ca2fbb
Show file tree
Hide file tree
Showing 21 changed files with 347 additions and 69 deletions.
35 changes: 27 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ I did this library to not have to deal with this OnActivityResult pattern. Never

RxActivityResult features:
--------------------------
* Launch the intent from any class, as long as you supply a valid activity instance.
* Launch the intent from any class, as long as you supply a valid activity or fragment instance.
* Get the intent back with the data encapsulated in an observable and keep going crazy chaining operations.

Setup
Expand All @@ -25,35 +25,54 @@ allprojects {
And add next dependencies in the build.gradle of the module:
```gradle
dependencies {
compile "com.github.VictorAlbertos:RxActivityResult:0.1"
compile "com.github.VictorAlbertos:RxActivityResult:0.2"
compile "io.reactivex:rxjava:1.1.0"
}
```

Usage
=====
Create an instance of the Intent you want to launch and supply it -with a valid reference to the current activity, to the static [RxActivityResult.startIntent](https://github.com/VictorAlbertos/RxActivityResult/blob/master/rx_activity_result/src/main/java/rx_activity_result/RxActivityResult.java#L35) method.
Call RxActivityResult.register in your Android Application class, supplying as parameter the current Android Application instance.

```java
public class SampleApp extends Application {

@Override public void onCreate() {
super.onCreate();
RxActivityResult.register(this);
}
}
```

You can call [RxActivityResult.on(this).startIntent(intent)](https://github.com/VictorAlbertos/RxActivityResult/blob/master/rx_activity_result/src/main/java/rx_activity_result/RxActivityResult.java) supplying both, an activity instance or a fragment instance.
Observe the emitted [Result](https://github.com/VictorAlbertos/RxActivityResult/blob/master/rx_activity_result/src/main/java/rx_activity_result/Result.java) item to know the resultCode and retrieve the associated data if appropriate.


```java
Intent takePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

RxActivityResult.startIntent(takePhoto, this)
RxActivityResult.on(this).startIntent(takePhoto)
.subscribe(result -> {
Intent data = result.data();
int resultCode = result.resultCode();

if (resultCode == RESULT_OK) {
showImage(data);
result.targetUI().showImage(data);
} else {
printUserCanceled();
result.targetUI().printUserCanceled();
}
});
```

Please pay attention to the targetUI() method in the Result object emitted.

This method returns a safety instance of the current Activity/Fragment. Because the original instance of the Activity/Fragment may be recreated (due to configuration changes or some other system events) it would be unsafety calling it.

Instead, you must call any method/variable of your Activity/Fragment from this instance encapsulated in the Result object.

Examples
--------
There is an example of RxActivityResult in the [app module](https://github.com/VictorAlbertos/RxActivityResult/tree/master/app)
There is an example of RxActivityResult using both activity and fragment in the [app module](https://github.com/VictorAlbertos/RxActivityResult/tree/master/app)

Author
-------
Expand Down
2 changes: 1 addition & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# If your project uses WebView startIntent JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
Expand Down
12 changes: 11 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
package="io.victoralbertos.app">

<application
android:name="app.SampleApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="app.MainActivity"
android:name="app.StartActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
Expand All @@ -18,6 +19,15 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name="app.HostActivitySampleFragment"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name="app.SampleActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" />
</application>

</manifest>
15 changes: 15 additions & 0 deletions app/src/main/java/app/HostActivitySampleFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package app;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import io.victoralbertos.app.R;

public class HostActivitySampleFragment extends AppCompatActivity {

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.host_activity_sample_fragment);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,26 @@
import io.victoralbertos.app.R;
import rx_activity_result.RxActivityResult;

public class MainActivity extends AppCompatActivity {
public class SampleActivity extends AppCompatActivity {

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setContentView(R.layout.sample_layout);

findViewById(R.id.bt_camera).setOnClickListener(view -> camera());
}

private void camera() {
Intent takePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

RxActivityResult.startIntent(takePhoto, this)
RxActivityResult.on(this).startIntent(takePhoto)
.subscribe(result -> {
Intent data = result.data();
int resultCode = result.resultCode();

if (resultCode == RESULT_OK) {
showImage(data);
result.targetUI().showImage(data);
} else {
printUserCanceled();
result.targetUI().printUserCanceled();
}
});
}
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/app/SampleApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app;

import android.app.Application;

import rx_activity_result.RxActivityResult;

public class SampleApp extends Application {

@Override public void onCreate() {
super.onCreate();
RxActivityResult.register(this);
}
}
54 changes: 54 additions & 0 deletions app/src/main/java/app/SampleFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package app;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import io.victoralbertos.app.R;
import rx_activity_result.RxActivityResult;

public class SampleFragment extends Fragment {

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.sample_layout, container, false);
return view;
}

@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getView().findViewById(R.id.bt_camera).setOnClickListener(view -> camera());
}

private void camera() {
Intent takePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

RxActivityResult.on(this).startIntent(takePhoto)
.subscribe(result -> {
Intent data = result.data();
int resultCode = result.resultCode();

if (resultCode == Activity.RESULT_OK) {
result.targetUI().showImage(data);
} else {
result.targetUI().printUserCanceled();
}
});
}

private void showImage(Intent data) {
Bitmap imageBitmap = (Bitmap) data.getExtras().get("data");
((ImageView) getView().findViewById(R.id.iv_thumbnail)).setImageBitmap(imageBitmap);
}

private void printUserCanceled() {
Toast.makeText(getActivity(), getString(R.string.user_canceled_action), Toast.LENGTH_LONG).show();
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/app/StartActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package app;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import io.victoralbertos.app.R;

public class StartActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_activity);

findViewById(R.id.bt_activity).setOnClickListener(view -> {
startActivity(new Intent(StartActivity.this, SampleActivity.class));
});

findViewById(R.id.bt_fragment).setOnClickListener(view -> {
startActivity(new Intent(StartActivity.this, HostActivitySampleFragment.class));
});
}
}
19 changes: 0 additions & 19 deletions app/src/main/res/layout/content_main.xml

This file was deleted.

14 changes: 14 additions & 0 deletions app/src/main/res/layout/host_activity_sample_fragment.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
android:id="@+id/sample_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="app.SampleFragment"
tools:layout="@layout/sample_layout" />

</LinearLayout>
19 changes: 19 additions & 0 deletions app/src/main/res/layout/start_activity.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<Button
android:id="@+id/bt_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/using_activity" />

<Button
android:id="@+id/bt_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/using_fragment" />

</LinearLayout>
2 changes: 1 addition & 1 deletion app/src/main/res/values-w820dp/dimens.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
(such as screen margins) for screens startIntent more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
3 changes: 2 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<string name="app_name">RxActivityResult</string>
<string name="action_settings">Settings</string>
<string name="camera">Camera</string>
<string name="gallery">Gallery</string>
<string name="user_canceled_action">User canceled action</string>
<string name="using_activity">Using activity</string>
<string name="using_fragment">Using fragment</string>
</resources>
2 changes: 1 addition & 1 deletion rx_activity_result/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# If your project uses WebView startIntent JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package rx_activity_result;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;

class ActivitiesLifecycleCallbacks {
private final Application application;
private Activity liveActivityOrNull;
private Application.ActivityLifecycleCallbacks activityLifecycleCallbacks;

public ActivitiesLifecycleCallbacks(Application application) {
this.application = application;
registerActivityLifeCycle();
}

private void registerActivityLifeCycle() {
if (activityLifecycleCallbacks != null) application.unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks);

activityLifecycleCallbacks = new Application.ActivityLifecycleCallbacks() {
@Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
liveActivityOrNull = activity;
}

@Override public void onActivityStarted(Activity activity) {}

@Override public void onActivityResumed(Activity activity) {
liveActivityOrNull = activity;
}

@Override public void onActivityPaused(Activity activity) {
liveActivityOrNull = null;
}

@Override public void onActivityStopped(Activity activity) {}

@Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}

@Override public void onActivityDestroyed(Activity activity) {}
};

application.registerActivityLifecycleCallbacks(activityLifecycleCallbacks);
}

Activity getLiveActivity() {
return liveActivityOrNull;
}
}
Loading

0 comments on commit 3ca2fbb

Please sign in to comment.