diff --git a/CHANGELOG.md b/CHANGELOG.md index ae02ab79f5..ac366478f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Enhancements +* Added support for using non-encrypted Realm in multiple processes from the same apk (#1091). + ### Bug Fixes ### Interal diff --git a/examples/multiProcessExample/.gitignore b/examples/multiProcessExample/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/examples/multiProcessExample/.gitignore @@ -0,0 +1 @@ +/build diff --git a/examples/multiProcessExample/build.gradle b/examples/multiProcessExample/build.gradle new file mode 100644 index 0000000000..6b2e8e5ed7 --- /dev/null +++ b/examples/multiProcessExample/build.gradle @@ -0,0 +1,38 @@ +apply plugin: 'com.android.application' +apply plugin: 'android-command' +apply plugin: 'realm-android' + +android { + compileSdkVersion rootProject.sdkVersion + buildToolsVersion rootProject.buildTools + + defaultConfig { + applicationId "io.realm.examples.realmmultiprocessexample" + targetSdkVersion rootProject.sdkVersion + minSdkVersion 9 + versionCode 1 + versionName "1.0" + } + + buildTypes { + release { + minifyEnabled true + signingConfig signingConfigs.debug + } + debug { + minifyEnabled true + } + } + + productFlavors { + } + + command { + monkey.events 2000 + } +} + +dependencies { + compile 'com.android.support:appcompat-v7:23.1.1' +} + diff --git a/examples/multiProcessExample/proguard-rules.pro b/examples/multiProcessExample/proguard-rules.pro new file mode 100644 index 0000000000..8456b3daec --- /dev/null +++ b/examples/multiProcessExample/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /home/cc/.android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/examples/multiProcessExample/src/main/AndroidManifest.xml b/examples/multiProcessExample/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..91862ee505 --- /dev/null +++ b/examples/multiProcessExample/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + diff --git a/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/AnotherProcessService.java b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/AnotherProcessService.java new file mode 100644 index 0000000000..d30116d996 --- /dev/null +++ b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/AnotherProcessService.java @@ -0,0 +1,43 @@ +package io.realm.examples.realmmultiprocessexample; + +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; + +import io.realm.Realm; + +public class AnotherProcessService extends Service { + + Handler handler; + + @Override + public void onCreate() { + super.onCreate(); + + handler = new Handler(Looper.myLooper()); + final Runnable runnable = new Runnable() { + @Override + public void run() { + Realm realm = Realm.getDefaultInstance(); + realm.beginTransaction(); + realm.copyToRealmOrUpdate(Utils.createStandaloneProcessInfo(AnotherProcessService.this)); + realm.commitTransaction(); + realm.close(); + handler.postDelayed(this, 1000); + } + }; + handler.postDelayed(runnable, 1000); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + @Override + public IBinder onBind(Intent intent) { + throw new UnsupportedOperationException("Not yet implemented"); + } +} diff --git a/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/MainActivity.java b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/MainActivity.java new file mode 100644 index 0000000000..b72f295a75 --- /dev/null +++ b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/MainActivity.java @@ -0,0 +1,90 @@ +/* + * Copyright 2014 Realm Inc. + * + * 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 io.realm.examples.realmmultiprocessexample; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Locale; + +import io.realm.Realm; +import io.realm.RealmChangeListener; +import io.realm.RealmResults; +import io.realm.examples.realmmultiprocessexample.models.ProcessInfo; + +public class MainActivity extends AppCompatActivity { + + private TextView textView; + private Realm realm; + private RealmResults processInfoResults; + + private RealmChangeListener> listener = + new RealmChangeListener>() { + @Override + public void onChange(RealmResults results) { + StringBuilder stringBuilder = new StringBuilder(); + + for (ProcessInfo processInfo : results) { + stringBuilder.append(processInfo.getName()); + stringBuilder.append("\npid: "); + stringBuilder.append(processInfo.getPid()); + stringBuilder.append("\nlast response time: "); + DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.ENGLISH); + stringBuilder.append(df.format(processInfo.getLastResponseDate())); + stringBuilder.append("\n------\n"); + } + textView.setText(stringBuilder.toString()); + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + textView = (TextView) findViewById(R.id.textView); + + if (realm == null) { + realm = Realm.getDefaultInstance(); + processInfoResults = realm.where(ProcessInfo.class).findAllAsync(); + processInfoResults.addChangeListener(listener); + } + + realm.beginTransaction(); + realm.copyToRealmOrUpdate(Utils.createStandaloneProcessInfo(this)); + realm.commitTransaction(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (realm != null) { + realm.close(); + realm = null; + processInfoResults = null; + } + } + + public void onStartButton(View button) { + Intent intent = new Intent(MainActivity.this, AnotherProcessService.class); + startService(intent); + button.setEnabled(false); + } +} diff --git a/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/MyApplication.java b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/MyApplication.java new file mode 100644 index 0000000000..75965412fa --- /dev/null +++ b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/MyApplication.java @@ -0,0 +1,16 @@ +package io.realm.examples.realmmultiprocessexample; + +import android.app.Application; + +import io.realm.Realm; +import io.realm.RealmConfiguration; + +public class MyApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + Realm.init(this); + RealmConfiguration configuration = new RealmConfiguration.Builder().deleteRealmIfMigrationNeeded().build(); + Realm.setDefaultConfiguration(configuration); + } +} diff --git a/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/Utils.java b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/Utils.java new file mode 100644 index 0000000000..cd12266dcd --- /dev/null +++ b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/Utils.java @@ -0,0 +1,41 @@ +package io.realm.examples.realmmultiprocessexample; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningAppProcessInfo; +import android.content.Context; +import android.os.Process; + +import java.util.Date; +import java.util.List; + +import io.realm.examples.realmmultiprocessexample.models.ProcessInfo; + +public class Utils { + + public static String getMyProcessName(Context context) { + String processName = ""; + ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); + List infoList= am.getRunningAppProcesses(); + if (infoList == null) { + throw new RuntimeException("getRunningAppProcesses() returns 'null'."); + } + for (RunningAppProcessInfo info : infoList) { + try { + if (info.pid == Process.myPid()) { + processName = info.processName; + } + } catch (Exception ignored) { + } + } + return processName; + } + + public static ProcessInfo createStandaloneProcessInfo(Context context) { + ProcessInfo processInfo = new ProcessInfo(); + processInfo.setName(getMyProcessName(context)); + processInfo.setPid(android.os.Process.myPid()); + processInfo.setLastResponseDate(new Date()); + + return processInfo; + } +} diff --git a/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/models/ProcessInfo.java b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/models/ProcessInfo.java new file mode 100644 index 0000000000..f956b50861 --- /dev/null +++ b/examples/multiProcessExample/src/main/java/io/realm/examples/realmmultiprocessexample/models/ProcessInfo.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014 Realm Inc. + * + * 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 io.realm.examples.realmmultiprocessexample.models; + +import java.util.Date; + +import io.realm.RealmObject; +import io.realm.annotations.PrimaryKey; +import io.realm.annotations.Required; + +public class ProcessInfo extends RealmObject { + @PrimaryKey + private String name; + private int pid; + @Required + private Date lastResponseDate; + + public int getPid() { + return pid; + } + + public void setPid(int pid) { + this.pid = pid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getLastResponseDate() { + return lastResponseDate; + } + + public void setLastResponseDate(Date lastResponseDate) { + this.lastResponseDate = lastResponseDate; + } +} diff --git a/examples/multiProcessExample/src/main/res/layout/activity_main.xml b/examples/multiProcessExample/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000000..79f8daf590 --- /dev/null +++ b/examples/multiProcessExample/src/main/res/layout/activity_main.xml @@ -0,0 +1,26 @@ + + + +