Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ Our app is designed to be easy to use and lightweight. Plus, it's free and open

Download Android Studio Tutorials: Java Edition from the Google Play Store and begin your Android development journey today. It's free, easy to use, and perfect for beginners.

## Architecture

The app follows the modern layered architecture recommended by Google. The UI layer observes
immutable state from ViewModels. Business logic is encapsulated in use case classes within the
domain layer, which interact with repositories in the data layer. Each screen now exposes its
operations through a small set of use cases. This pattern was inspired by the
[Android Clean Architecture](https://github.com/android10/Android-CleanArchitecture) sample but
implemented in a simplified form to avoid adding heavy dependencies. The result keeps the UI
simple and ensures a clear separation of concerns across the whole app.

## Feedback

We are constantly updating and improving Android Studio Tutorials: Java Edition to give you the best possible experience. If you have suggested features or improvements, please leave a review. If something isn't working correctly, let us know so we can fix it.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.about;

import com.d4rk.androidtutorials.java.ui.screens.about.repository.AboutRepository;

/** Provides current year as a string. */
public class GetCurrentYearUseCase {
private final AboutRepository repository;

public GetCurrentYearUseCase(AboutRepository repository) {
this.repository = repository;
}

public String invoke() {
return repository.getCurrentYear();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.about;

import com.d4rk.androidtutorials.java.ui.screens.about.repository.AboutRepository;

/** Returns the formatted app version string. */
public class GetVersionStringUseCase {
private final AboutRepository repository;

public GetVersionStringUseCase(AboutRepository repository) {
this.repository = repository;
}

public String invoke() {
return repository.getVersionString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.android;

import com.d4rk.androidtutorials.java.ui.screens.android.repository.LessonRepository;

/** Retrieves lesson data by name. */
public class GetLessonUseCase {
private final LessonRepository repository;

public GetLessonUseCase(LessonRepository repository) {
this.repository = repository;
}

public LessonRepository.Lesson invoke(String lessonName) {
return repository.getLesson(lessonName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.d4rk.androidtutorials.java.domain.help;

import android.app.Activity;
import com.d4rk.androidtutorials.java.ui.screens.help.repository.HelpRepository;
import com.google.android.play.core.review.ReviewInfo;

/** Launches the in-app review flow. */
public class LaunchReviewFlowUseCase {
private final HelpRepository repository;

public LaunchReviewFlowUseCase(HelpRepository repository) {
this.repository = repository;
}

public void invoke(Activity activity, ReviewInfo info) {
repository.launchReviewFlow(activity, info);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.help;

import com.d4rk.androidtutorials.java.ui.screens.help.repository.HelpRepository;

/** Requests the Google Play review flow. */
public class RequestReviewFlowUseCase {
private final HelpRepository repository;

public RequestReviewFlowUseCase(HelpRepository repository) {
this.repository = repository;
}

public void invoke(HelpRepository.OnReviewInfoListener listener) {
repository.requestReviewFlow(listener);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.d4rk.androidtutorials.java.domain.home;

import com.d4rk.androidtutorials.java.ui.screens.home.repository.HomeRepository;

/** Use case that provides the daily tip text. */
public class GetDailyTipUseCase {
private final HomeRepository repository;

public GetDailyTipUseCase(HomeRepository repository) {
this.repository = repository;
}

/**
* Returns today's tip string.
*/
public String invoke() {
return repository.getDailyTip();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.d4rk.androidtutorials.java.domain.home;

import com.d4rk.androidtutorials.java.data.model.PromotedApp;
import com.d4rk.androidtutorials.java.ui.screens.home.repository.HomeRepository;

import java.util.List;

/** Use case that fetches promoted apps from the repository. */
public class GetPromotedAppsUseCase {
private final HomeRepository repository;

public interface Callback {
void onResult(List<PromotedApp> apps);
}

public GetPromotedAppsUseCase(HomeRepository repository) {
this.repository = repository;
}

/**
* Fetches the promoted apps and returns them via the callback.
*/
public void invoke(Callback callback) {
repository.fetchPromotedApps(callback::onResult);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.main;

import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;

/** Applies the saved language preference. */
public class ApplyLanguageSettingsUseCase {
private final MainRepository repository;

public ApplyLanguageSettingsUseCase(MainRepository repository) {
this.repository = repository;
}

public void invoke() {
repository.applyLanguageSettings();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.main;

import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;

/** Applies theme preference and returns true if changed. */
public class ApplyThemeSettingsUseCase {
private final MainRepository repository;

public ApplyThemeSettingsUseCase(MainRepository repository) {
this.repository = repository;
}

public boolean invoke(String[] darkModeValues) {
return repository.applyThemeSettings(darkModeValues);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.d4rk.androidtutorials.java.domain.main;

import android.content.Intent;
import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;

/** Creates an intent for the app shortcut. */
public class BuildShortcutIntentUseCase {
private final MainRepository repository;

public BuildShortcutIntentUseCase(MainRepository repository) {
this.repository = repository;
}

public Intent invoke(boolean isInstalled) {
return repository.buildShortcutIntent(isInstalled);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.d4rk.androidtutorials.java.domain.main;

import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;
import com.google.android.play.core.appupdate.AppUpdateManager;

/** Provides the AppUpdateManager instance. */
public class GetAppUpdateManagerUseCase {
private final MainRepository repository;

public GetAppUpdateManagerUseCase(MainRepository repository) {
this.repository = repository;
}

public AppUpdateManager invoke() {
return repository.getAppUpdateManager();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.main;

import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;

/** Returns bottom navigation label visibility preference. */
public class GetBottomNavLabelVisibilityUseCase {
private final MainRepository repository;

public GetBottomNavLabelVisibilityUseCase(MainRepository repository) {
this.repository = repository;
}

public String invoke(String key, String defaultValue) {
return repository.getBottomNavLabelVisibility(key, defaultValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.main;

import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;

/** Returns the default tab preference string. */
public class GetDefaultTabPreferenceUseCase {
private final MainRepository repository;

public GetDefaultTabPreferenceUseCase(MainRepository repository) {
this.repository = repository;
}

public String invoke(String key, String defaultValue) {
return repository.getDefaultTabPreference(key, defaultValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.d4rk.androidtutorials.java.domain.main;

import android.content.pm.PackageManager;
import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;

/** Checks if an app is installed by package name. */
public class IsAppInstalledUseCase {
private final MainRepository repository;

public IsAppInstalledUseCase(MainRepository repository) {
this.repository = repository;
}

public boolean invoke(PackageManager pm, String packageName) {
return repository.isAppInstalled(pm, packageName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.main;

import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;

/** Marks that the startup screen has been shown. */
public class MarkStartupScreenShownUseCase {
private final MainRepository repository;

public MarkStartupScreenShownUseCase(MainRepository repository) {
this.repository = repository;
}

public void invoke() {
repository.markStartupScreenShown();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.main;

import com.d4rk.androidtutorials.java.ui.screens.main.repository.MainRepository;

/** Determines if the startup screen should be shown. */
public class ShouldShowStartupScreenUseCase {
private final MainRepository repository;

public ShouldShowStartupScreenUseCase(MainRepository repository) {
this.repository = repository;
}

public boolean invoke() {
return repository.shouldShowStartupScreen();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.d4rk.androidtutorials.java.domain.quiz;

import com.d4rk.androidtutorials.java.data.model.QuizQuestion;
import com.d4rk.androidtutorials.java.ui.screens.quiz.repository.QuizRepository;
import java.util.List;

/** Loads quiz questions from assets. */
public class LoadQuizQuestionsUseCase {
private final QuizRepository repository;

public LoadQuizQuestionsUseCase(QuizRepository repository) {
this.repository = repository;
}

public List<QuizQuestion> invoke() {
return repository.loadQuestions();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.d4rk.androidtutorials.java.domain.settings;

import com.d4rk.androidtutorials.java.ui.screens.settings.repository.SettingsRepository;

/** Applies the Firebase consent settings. */
public class ApplyConsentUseCase {
private final SettingsRepository repository;

public ApplyConsentUseCase(SettingsRepository repository) {
this.repository = repository;
}

public void invoke() {
repository.applyConsent();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.d4rk.androidtutorials.java.domain.settings;

import android.content.SharedPreferences;
import com.d4rk.androidtutorials.java.ui.screens.settings.repository.SettingsRepository;

/** Provides shared preferences used by the settings screen. */
public class GetSharedPreferencesUseCase {
private final SettingsRepository repository;

public GetSharedPreferencesUseCase(SettingsRepository repository) {
this.repository = repository;
}

public SharedPreferences invoke() {
return repository.getSharedPreferences();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.d4rk.androidtutorials.java.domain.settings;

import com.d4rk.androidtutorials.java.ui.screens.settings.repository.SettingsRepository;

/** Handles a preference change and returns true if theme changed. */
public class OnPreferenceChangedUseCase {
private final SettingsRepository repository;

public OnPreferenceChangedUseCase(SettingsRepository repository) {
this.repository = repository;
}

public boolean invoke(String key) {
repository.handlePreferenceChange(key);
return repository.applyTheme();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.d4rk.androidtutorials.java.domain.startup;

import android.app.Activity;
import com.d4rk.androidtutorials.java.ui.screens.startup.repository.StartupRepository;

/** Loads and shows the consent form if required. */
public class LoadConsentFormUseCase {
private final StartupRepository repository;

public LoadConsentFormUseCase(StartupRepository repository) {
this.repository = repository;
}

public void invoke(Activity activity, StartupRepository.OnFormError onError) {
repository.loadConsentForm(activity, onError);
}
}
Loading