2017-03-02 2 views
0

Ich bin neu in einem Android-Projekt und leider ist das alte Team verlassen und ich bin ahnungslos.Schließen Realm über verschiedene Dateien

das Projekt ist wie folgt strukturiert

Aktivitäten, Fragmente, Reich (die CRUD Dateien enthält & DAO-Dateien als auch)

mainActivity:

 protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       setContentView(R.layout.menu_drawer_activity); 
       ButterKnife.bind(this); 
       EventBus.getDefault().register(this); 
       setSupportActionBar(toolbar); 
       String ChannelId = UAirship.shared().getPushManager().getChannelId(); 

       Realm.init(this); 
       RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().schemaVersion(2).deleteRealmIfMigrationNeeded().build(); 
       Realm.setDefaultConfiguration(realmConfiguration); // Make this Realm the default 
       realm = Realm.getInstance(realmConfiguration); 

       showInitalFragment(); 
       setUserInfoInNaviagtionDrawer(); 
       setupUI(); 
      } 

// some logic 

     @Override 
     protected void onDestroy() { 
      EventBus.getDefault().unregister(this); 
      realm.close(); 
      super.onDestroy(); 
     } 

nun in CRUD Dateien und DOA dieser Was passiert:

CRUDfile1.java: http://ideone.com/fs0RYo

DAOfile1.java: http://ideone.com/1klhW8

jetzt das Problem ist, dass es ein lof ot Reich Instanzen erstellt und bleiben viel Speicher genommen und verursacht manchmal die App zum Absturz zu bringen, und ich bin nicht in der Lage zu schließen sie geöffnet (Die App stürzt daher die Kommentare ab). irgendwelche Ideen wie soll ich das beheben?

Antwort

0

jetzt das Problem ist, dass es ein lof ot Reich Instanzen geschaffen ist und bleiben daher viel Speicher genommen und verursacht manchmal die App zum Absturz zu bringen, und ich bin nicht in der Lage zu schließen, sie (die App stürzt die geöffnet Bemerkungen). irgendwelche Ideen wie soll ich das beheben?

Realm-Instanzen werden Referenz gezählt, an einem bestimmten Thread bedeutet, gibt es eigentlich nur eine geöffnete Instanz. Die Instanz wird jedoch nur geschlossen, wenn alle "lokalen Realm-Instanzen" geschlossen sind.

Zum Beispiel

Realm realm = Realm.getDefaultInstance(); 
Realm realm2 = Realm.getDefaultInstance(); 

realm2.close(); 
realm.close(); // <-- this is when Realm is released for the given thread 

In Wirklichkeit sie beide auf dem gleichen „underlying Realm“, auch wenn sie als zwei verschiedene „lokalen Realm Instanzen“ behandelt werden.

Sie haben also nicht zu viel Speicher wegen "Öffnen zu viele".


Sie können jedoch über genügend Arbeitsspeicher ausgeführt und abstürzen, wenn Sie offene Realm-Instanzen auf nicht-Looper Hintergrund-Threads und schließen Sie sie nicht.

Also auf Hintergrund-Threads, sollen Sie das folgende Setup sehen:

try(Realm realm = Realm.getDefaultInstance()) { 
    // do things here 
} // auto-close 

oder

Realm realm = null; 
try { 
    realm = Realm.getDefaultInstance(); 
    realm.executeTransaction(new Realm.Transaction() { 
     // ... actual transaction code here 
    }); 
} finally { 
    if(realm != null) { 
     realm.close(); 
    } 
} 

Diese ganze RealmObject.getRealmObject(Context) Ding sieht völlig falsch.

Ich habe Leute gesehen, dies zu tun, Realm.getDefaultInstance().where(...) das zum Beispiel erstellt eine Instanz, die Sie niemals schließen können, und Sie sollten sie schließen.

+0

okay, können Sie mir ein Beispiel für den Code geben, den ich gepostet habe? – xxqxpxx

+0

Oh wow, deine Kollegen zeichnen die "RealmResults" (eine Liste) in eine 'ArrayList', aber sie behalten sie als verwaltete Objekte. Und die 'get'-Methoden geben keine Liste zurück, sie nehmen eine Eingabeliste, die so modifiziert wurde, dass sie die neue Liste enthält ... wow, das ist super-schlecht schlecht. Dies ist die schlimmste von zwei Welten. – EpicPandaForce

+0

ich kenne seine beschissene Arbeit. Entschuldigung, du musst folgendes sehen:/ – xxqxpxx

0

Ändern Sie alle Ihre Methoden in beiden Klassen von

{ 
    Realm realm = RealmObject.getRealmObject(MyApplication.getAppContext()); 
    <your-code> 
} 

an (wenn Ihr minSdkVersion> = 19)

{ 
    try(Realm realm = RealmObject.getRealmObject(MyApplication.getAppContext())) { 
     <your-code> 
    } 
} 

oder

{ 
    Realm realm = RealmObject.getRealmObject(MyApplication.getAppContext())); 
    try { 
     <your-code> 
    } catch (Exception e) { 
     realm.cancelTransaction(); 
    } finally { 
     if (realm != null) { 
      realm.close(); 
     } 
    } 
} 

Deshalb finden Sie alle Bereich schließen Instanzen.

+0

Ich versuchte 'public static void insertCollectionsObject (endgültig BorrowUnsubscribedBundleResponse collectionObj) { Realm realm = getRealmObject (getAppContext()); ArrayList borrowBundles = (ArrayList ) collectionObj.getLstBorrowBundles(); realm.close(); } ' und würde die App zum Absturz bringen oder Daten nicht erhalten. Ich werde versuchen, was Sie vorgeschlagen haben – xxqxpxx

-1

Die beste Praxis sagt, dass alle Ihre Methoden halten bestimmte Arten von Operationen in einzelner Klasse führen leicht zu pflegen und Ihre Dateistruktur ordentlich und sauber zu halten:

Fügen Sie Ihr Reich Abfragen in einzelner Controller-Klasse und Reich Instanz in diesem Controller-Klasse nur:

public class RealmController { 

    private static RealmController instance; 
    private final Realm realm; 

    public RealmController(Application application) { 
     realm = Realm.getDefaultInstance(); 
    } 

    public static RealmController with(Fragment fragment) { 

     if (instance == null) { 
      instance = new RealmController(fragment.getActivity().getApplication()); 
     } 
     return instance; 
    } 

    public static RealmController with(Activity activity) { 

     if (instance == null) { 
      instance = new RealmController(activity.getApplication()); 
     } 
     return instance; 
    } 

    public static RealmController with(Application application) { 

     if (instance == null) { 
      instance = new RealmController(application); 
     } 
     return instance; 
    } 

    public static RealmController getInstance() { 

     return instance; 
    } 

    public Realm getRealm() { 

     return realm; 
    } 

    //Refresh the realm istance 
    public void refresh() { 

     realm.refresh(); 
    } 

    //clear all objects from Book.class 
    public void clearAll() { 

     realm.beginTransaction(); 
     realm.clear(Book.class); 
     realm.commitTransaction(); 
    } 

    //find all objects in the Book.class 
    public RealmResults<Book> getBooks() { 

     return realm.where(Book.class).findAll(); 
    } 

    //query a single item with the given id 
    public Book getBook(String id) { 

     return realm.where(Book.class).equalTo("id", id).findFirst(); 
    } 

    //check if Book.class is empty 
    public boolean hasBooks() { 

     return !realm.allObjects(Book.class).isEmpty(); 
    } 

    //query example 
    public RealmResults<Book> queryedBooks() { 

     return realm.where(Book.class) 
       .contains("author", "Author 0") 
       .or() 
       .contains("title", "Realm") 
       .findAll(); 

    } 
} 

nun eine Methode machen Realm Instanz dieser Klasse zu schließen, wenn Controller Thread Änderungen oder Fragment/Aktivität zerstört:

public void closeRealmInstance(){ 
    if(realm != null){ 
    realm.close(); 
    } 
} 

Jetzt sind Sie gut zu gehen. Zugang Reich, wie unten in Fragment:

RealmController realmController = new RealmController(yourContext); 
BookClass bookObj = realmController.getBook(); 
realmController.closeRealmInstance(); 

oben Struktur verwenden Sie erhalten Ihren Code vereinfacht, und Sie werden wissen besser, was in vorhandenen Code geschieht. Viel Spaß beim Codieren !!! Upvote, wenn es geholfen hat.

+0

Nein Nein Nein Nono Nein Nono Nein. 'RealmController' und der Ravi Tamada Artikel ist BAD. Hör auf es zu zitieren. Lesen Sie mehr [hier] (https://medium.com/@Zhuinden/how-to-use-realm-for-android-like-a-champ-and-how-to-tell-if-youre-doing -it-falsch-ac4f66b7f149). – EpicPandaForce

+0

Auch 'refresh()' wurde in 0.90.0 entfernt. Also sogar das Beispiel ist veraltet, wenn man bedenkt Realm ist bei 3.0.0 – EpicPandaForce

Verwandte Themen