Preamble
I like to use realm in my project because of its speed and flexibility when it comes to listening to changes in data from the database, but that’s not when I’m working on a clean architecture based project because of its independence. between floors in the project.
Way
Is there any way? Yes, and there are many, let’s try listing it out:
Realm + Broadcast Receiver —> is too resource-intensive, need to write a listen subscribe function and unsubscribe from Broadcast Receiver
Realm + Live Data —> is good, but the live data is of android and the business layer (Domain) should not contain android in it.
Realm + Rx —> good, but requires the entire thread to be processed in the main thread (affecting the UI)
So is there any other way, I was desperate until Flow in Coroutines appeared the flexibility in multithreading that attracted me to a great discovery when I found a solution for it =)), now Let’s try to code
Code
Code Base
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<span class="token annotation builtin">@OptIn</span> <span class="token punctuation">(</span> ExperimentalCoroutinesApi <span class="token operator">::</span> <span class="token keyword">class</span> <span class="token punctuation">)</span> <span class="token keyword">fun</span> <span class="token operator"><</span> S <span class="token operator">:</span> RealmObject <span class="token punctuation">,</span> R <span class="token operator">></span> <span class="token function">handlerAndReturnListFlow</span> <span class="token punctuation">(</span> block <span class="token operator">:</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">-></span> RealmQuery <span class="token operator"><</span> S <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token operator">:</span> Flow <span class="token operator"><</span> List <span class="token operator"><</span> R <span class="token operator">></span> <span class="token operator">></span> <span class="token operator">=</span> callbackFlow <span class="token punctuation">{</span> <span class="token keyword">val</span> results <span class="token operator">=</span> <span class="token function">block</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">findAllAsync</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">!!</span> <span class="token keyword">val</span> realm <span class="token operator">=</span> results <span class="token punctuation">.</span> realm <span class="token operator">!!</span> <span class="token keyword">val</span> listener <span class="token operator">=</span> RealmChangeListener <span class="token operator"><</span> RealmResults <span class="token operator"><</span> S <span class="token operator">></span> <span class="token operator">></span> <span class="token punctuation">{</span> t <span class="token operator">-></span> <span class="token function">offer</span> <span class="token punctuation">(</span> realm <span class="token punctuation">.</span> <span class="token function">copyFromRealm</span> <span class="token punctuation">(</span> t <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> results <span class="token punctuation">.</span> <span class="token function">addChangeListener</span> <span class="token punctuation">(</span> listener <span class="token punctuation">)</span> <span class="token function">offer</span> <span class="token punctuation">(</span> realm <span class="token punctuation">.</span> <span class="token function">copyFromRealm</span> <span class="token punctuation">(</span> results <span class="token punctuation">)</span> <span class="token punctuation">)</span> awaitClose <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span> realm <span class="token punctuation">.</span> isClosed <span class="token punctuation">)</span> <span class="token punctuation">{</span> results <span class="token punctuation">.</span> <span class="token function">removeChangeListener</span> <span class="token punctuation">(</span> listener <span class="token punctuation">)</span> realm <span class="token punctuation">.</span> <span class="token function">close</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span> <span class="token function">flowOn</span> <span class="token punctuation">(</span> Dispatchers <span class="token punctuation">.</span> Main <span class="token punctuation">)</span> <span class="token comment">// đẩy bộ lắng nghe thay đổi dữ liệu vào trong luồng main để tận dụng cơ chế looper của main</span> <span class="token comment">/*.flowOn(android.os.Handler(HandlerThread("RealmDb").apply { start() }.looper).asCoroutineDispatcher("db"))*/</span> <span class="token comment">// đẩy bộ lắng nghe thay đổi dữ liệu vào trong luồng background, nhưng hãy chắc chắn rằng bạn quản lý tốt về thread</span> <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">{</span> <span class="token comment">// chuyển đổi entity database S sang entity R</span> <span class="token punctuation">}</span> |
Code in Database
1 2 3 4 |
<span class="token keyword">fun</span> <span class="token function">getAll</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=</span> handlerAndReturnListFlow <span class="token punctuation">{</span> Realm <span class="token punctuation">.</span> <span class="token function">getDefaultInstance</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">where</span> <span class="token punctuation">(</span> TestObject <span class="token operator">::</span> <span class="token keyword">class</span> <span class="token punctuation">.</span> java <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Code in Repository
1 2 |
<span class="token keyword">fun</span> <span class="token function">getAll</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=</span> testDb <span class="token punctuation">.</span> <span class="token function">getAll</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
Code in UseCase
1 2 |
<span class="token keyword">fun</span> <span class="token function">execute</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=</span> testRepository <span class="token punctuation">.</span> <span class="token function">getAll</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
Code in ViewModel
1 2 3 |
<span class="token keyword">fun</span> listTest <span class="token operator">=</span> getAllTest <span class="token punctuation">.</span> <span class="token function">execute</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">asLiveData</span> <span class="token punctuation">(</span> Dispatchers <span class="token punctuation">.</span> IO <span class="token punctuation">)</span> <span class="token comment">// yêu cầu xử lý trong luồng backgroud</span> |
Code in Activity
1 2 3 4 |
viewModel <span class="token punctuation">.</span> listTest <span class="token punctuation">.</span> <span class="token function">observe</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">d</span> <span class="token punctuation">(</span> <span class="token string">"HoangAnhTuan95Ptit"</span> <span class="token punctuation">,</span> <span class="token string">"onCreate: <span class="token interpolation"><span class="token delimiter variable">${</span> it <span class="token punctuation">.</span> size <span class="token delimiter variable">}</span></span> "</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
References
Think of it myself =))), maybe I will write an article on medium
Conclusion
I hope to help you in working with realm in the clean architecture. If you have any questions, don’t hesitate to comment on the article, I will try to answer. Thanks