2017-03-02 22 views
0

我剛剛接觸了一個android項目,不幸的是老團隊已經離開了,我仍然無能爲力。關閉跨越不同文件的領域

如下

活動,片段,境界(包含CRUD文件& DAO文件以及)項目的結構

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(); 
     } 
現在CRUD文件和DOA這裏面

發生了什麼事:

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

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

現在的問題是,有一個LOF OT領域實例創建並保持打開大量的內存取,有時會導致應用程序崩潰,我無法將其關閉(該應用程序將崩潰,因此評論)。任何想法我應該如何解決這個問題?

回答

0

現在的問題是,有一個LOF OT領域實例創建並保持打開大量的內存取,有時會導致應用程序崩潰,我無法將其關閉(應用程序將因此崩潰註釋 )。任何想法我應該如何解決這個問題?

領域實例的引用計數,一個給定的線程上的意思,實際上只有一個開放實例。但只有當所有「本地領域實例」都關閉時,實例纔會關閉。

例如,

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

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

在現實中,它們都指向同一個「潛在的境界」,即使他們被視爲兩個不同的「本地領域實例」。

所以你不會因爲「打開太多」而導致內存不足。


但是,您可以運行內存不足和崩潰如果非活套後臺線程您開放領域實例,並且不關閉它們

所以在後臺線程,你應該看到下面的設置:

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

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

這整個RealmObject.getRealmObject(Context)東西看起來完全錯誤的。

我見過這樣的人,Realm.getDefaultInstance().where(...)這個例子創建了一個你永遠不能關閉的實例,你應該關閉它們。

+0

沒關係,你能給我一個關於我發佈的代碼的例子嗎? – xxqxpxx

+0

哦,哇,你的同伴將'RealmResults'(這是一個List)映射到一個'ArrayList',但它們將它們作爲管理對象。而'get'方法實際上並不返回一個列表,他們接受一個輸入列表,該列表被修改爲包含新列表....哇,這是超級糟糕的。這是兩個世界中最糟糕的。 – EpicPandaForce

+0

我知道它的低劣工作。對不起,你必須看到這個:/ – xxqxpxx

0

變化這兩個類所有的方法,從

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

到(如果你的minSdkVersion> = 19)

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

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

因此,您將關閉所有境界實例。

+0

我試過 'public static void insertCollectionsObject(final BorrowUnsubscribedBundleResponse collectionObj){ Realm realm = getRealmObject(getAppContext()); ArrayList borrowBundles =(ArrayList )collectionObj.getLstBorrowBundles(); realm.close(); }' 並且會導致應用程序崩潰或無法獲取數據。我會嘗試你的建議 – xxqxpxx

-1

最好的做法表示保留所有的方法,以在單一類執行特定類型的操作很容易地維護和保持你的文件結構天工與清新:

添加你的境界查詢在此單個控制器類和領域實例唯一的控制器類:

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(); 

    } 
} 

現在使一個方法來關閉這個控制器類的領域實例當線程改變或片段/活性破壞:

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

現在,你很好去。如下訪問領域中的片段:

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

使用上述結構,你會得到你的代碼簡化,你會更瞭解正在發生的事情現有的代碼。享受編碼! Upvote,如果它幫助。

+0

不,不,不諾諾不諾諾沒有。 'RealmController'和Ravi Tamada的文章是壞的。停止引用它。閱讀更多關於[這裏](https://medium.com/@Zhuinden/how-to-use-realm-for-android-like-a-champ-and-how-to-tell-if-youre-doing - 它-錯ac4f66b7f149)。 – EpicPandaForce

+0

另外'refresh()'在0.90.0中被刪除。所以即使這個例子已經過時了,考慮Realm在3.0.0 – EpicPandaForce