Mobile Development 12 min read

Addressing Common Android Development Issues with the Snowball Onion Architecture

This article examines typical Android development challenges such as lack of standard architecture, lifecycle management, and testing difficulties, and presents the Snowball onion architecture—an MVVM‑based, RxJava‑powered framework with reusable components, best‑practice guidelines, and a supporting xueqiu‑onion library.

Snowball Engineer Team
Snowball Engineer Team
Snowball Engineer Team
Addressing Common Android Development Issues with the Snowball Onion Architecture

Common Development Issues

Writing high‑quality software is difficult; the Snowball client team often encounters problems such as lack of standard architecture, violation of the single‑responsibility principle, lifecycle management difficulties, poor unit‑testability, and inconsistent coding style.

Overview

The Snowball page architecture combines open‑source libraries, functional reactive programming, and MVVM to provide a reusable, testable, lifecycle‑safe framework that can be applied to any application.

RxJava Support

The implementation relies on RxJava, RxRelay and RxLifecycle to provide observable data sources and safe lifecycle binding.

MVVM Architecture

View – interacts with the user.

ViewModel – implements minimal business requirements.

Model – contains the actual business logic.

Repository – supplies data from network, local cache, or system services.

Best Practice Example

A concrete example shows how to implement a comment‑detail screen using the Snowball architecture.

Requirement

Display comment details returned by a REST API and support pull‑to‑load‑more.

UI Implementation

Files: CommentsDetail.kt, CommentsDetailActivity.kt, activity_comments_detail.xml, CommentsDetailViewModel.kt.

class CommentsDetailViewModel : XQViewModel {
    fun loadCommentsDetail(articleId: String) { ... }
}
class CommentsDetailActivity : Activity {
    var articleId: String
    var viewModel: CommentsDetailViewModel
    var refreshLayout: RefreshLayout
    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        articleId = intent.getStringExtra("ARTICLE_ID")
        viewModel = CommentsDetailViewModel()
        viewModel.loadCommentsDetail(articleId)
        refreshLayout.setOnLoadMoreListener { viewModel.loadCommentsDetail(articleId) }
    }
}

The ViewModel exposes signals for comment data and loading errors; the Activity binds to these signals and updates the UI.

Business Logic Implementation

Retrofit is used for network requests; the Model handles caching and transforms errors into normal signals.

interface ApiRepository {
    @GET("/article/{articleId}")
    fun loadCommentsDetail(@Path("articleId") articleId: String): Observable
}

The Model combines cached data with network data:

class CommentsModel : XQModel {
    val apiRepo = ApiRepository.getInstance()
    val cacheDao = CommentsCacheDao.getInstance()
    fun loadCommentsDetail(articleId: String): Observable
=
        cacheDao.getComments(articleId).concatWith(apiRepo.loadCommentsDetail(articleId))
}

Lifecycle Management

RxLifecycle is used to bind ViewModel streams to the Activity lifecycle, preventing memory leaks.

viewModel.commentsDetail
    .compose(bindToLifecycle())
    .subscribe { comments -> updateCommentsUI(comments) }

Second Requirement – Like Feature

A separate FabulousViewModel handles comment “like” actions, demonstrating single‑responsibility and reusability.

class CommentsDetailActivity : RxActivity {
    var commentsDetailViewModel: CommentsDetailViewModel
    var fabulousViewModel: FabulousViewModel
    var btnFabulousButton: Button
    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        bindViewModel()
        btnFabulousButton.setOnClickListener { fabulousViewModel.fabulousComment(commentId) }
    }
    private fun bindViewModel() {
        commentsDetailViewModel.commentsDetail.subscribe { updateCommentsUI(it) }
        commentsDetailViewModel.loadingError.subscribe { showErrorMessage(it) }
        fabulousViewModel.fabulousSuccess.subscribe { showMessage(it.result) }
        fabulousViewModel.fabulousFailure.subscribe { showErrorMessage(it) }
    }
}

Final Architecture

Diagrams (omitted) illustrate the onion‑style layered architecture where dependencies point inward, keeping inner layers stable and minimizing impact of changes.

xueqiu‑onion Framework

The framework abstracts RxJava and the architecture, providing thread‑switching transformers, unified event handling, lifecycle binding, signal wrappers, and a DI container to simplify development.

Summary

The article reviews common Android development problems, introduces the Snowball onion architecture and its components, demonstrates a practical implementation, and presents the xueqiu‑onion framework as a reusable solution for building robust mobile applications.

Mobile DevelopmentAndroidBest PracticesMVVMRxJavaonion architecture
Snowball Engineer Team
Written by

Snowball Engineer Team

Proactivity, efficiency, professionalism, and empathy are the core values of the Snowball Engineer Team; curiosity, passion, and sharing of technology drive their continuous progress.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.