들어가며..

최근에 Vibe Coding [1,2] 이라는 이야기가 많이 회자되고 있다. 개발자는 구조나 Product에 집중하고 실재 코딩 작업은 LLM에 맞기는 것이라고 한다. VSCode에 통합되어 있는 AI도구인 Cursor에서는 Agent[3]라는 제품도 나와서 이러한 트렌드를 더 가속화 하는 것으로 보인다. Cursor가 이미 IDE와 결함되어 있고, Agent 그리고 Ask 기능을 이미 제공하고 있기 때문에 여기서 설명하는 내용이 이미 필요 없을 수 있다. 하지만, Cursor를 사용하지 않고도 가능하다고 하면 Cursor를 사용하지 못하기 때문에 AI 도구를 이용해서 효과를 내지 못하는 것은 아니라는 것의 반증이기도 할 것 같다.

나의 사례

여기서 다루려는 내용은 아래 내용으로 나누어 볼 수 있다.

  1. 기존에 존재하는 코드를 이해하고 
  2. 우리가 원하는 기능을 어떻게 구현할지 결정하고
  3. 구현하는 코드를 만들어 적용

 

1번은 우리가 이미 구현하고 있는 Android App기준으로 이 부분은 다른 사례에 적용한다면 개발 환경에 따라 다를 수 있을 것 같다. 이 Android App에 대해 분석하는 예는 따로 설명한다[4]. 2번 부터 3번까지의 경우, Android App 기준으로 하나의 예를 가지고 따라가 보자. 물론 상황에 따라 다를 수 있음을 이해하자.

원하는 기능의 구현

이 부분은 필자의 사례이므로 상황에 따라 많이 다를 수 있다. 우리는 사용자가 특정 기간 동안 다른 동작을 해서 주의가 산만해 지는 것을 확인하기 위해 휴대폰에서 특정 앱을 사용하는 것을 모니터링 하는 것을 구현하려고 했다. 이와 관련해서 ChatGPT에 Prompting해 본 결과 중 일부를 살펴 보자.

Prompt: 너는 pytorch 및 tensorflow의 전문가이고, 동영상 처리에 대한 전문가야. Android에 대해서도 잘 알고 있는 전문가야. 휴대폰의 사용자가 휴대폰 사용하는 동안 어떤 어플리케이션을 사용하고 있는지 알아 내는 모듈을 개발하려고해. 이를 알아내는 방법을 여러가지 제안해줘

ChatGPT said:  (7가지를 이야기 했지만, 아래 3가지만 추출)
휴대폰에서 사용자가 어떤 애플리케이션을 사용하는지 알아내는 모듈을 개발하려면 아래와 같은 여러 가지 접근 방법을 고려할 수 있습니다. 각 접근법은 기술적인 제약, 성능, 그리고 보안 문제를 고려해야 합니다.

 

1. Accessibility Services 활용
- 방법: Android의 접근성 서비스(Accessibility Service)를 이용하면 사용자가 현재 활성화된 앱과 상호작용하는 내용을 감지할 수 있습니다.
- 장점: 사용자가 상호작용하는 앱에 대한 정보를 비교적 간단하게 가져올 수 있습니다.
- 단점: 사용자 동의가 필요하며, 민감한 정보를 처리하기 때문에 오용 시 보안 문제가 발생할 수 있습니다.
- 구현:
    1. `AccessibilityService` 클래스 구현.
    2. `onAccessibilityEvent` 메서드에서 앱 사용 데이터를 수집.

 

2. UsageStatsManager 활용
- 방법: Android의 `UsageStatsManager` API를 사용하여 최근에 사용된 애플리케이션 목록 및 사용 시간을 가져올 수 있습니다.
- 장점: 시스템 API를 사용하므로 안정적이고 공식적인 접근 방식.
- 단점: 사용자에게 Usage Access 권한을 별도로 요청해야 합니다.
- 구현:
    1. `UsageStatsManager` 인스턴스 생성.
    2. `queryUsageStats` 메서드로 주어진 기간 동안 사용된 앱의 데이터를 수집.

 

3. Foreground Service 및 Activity Recognition API
- 방법: 포어그라운드 서비스와 Activity Recognition API를 조합하여 현재 활성화된 앱 상태를 모니터링.
- 장점: 백그라운드에서 안정적으로 작동.
- 단점: 높은 배터리 소모 가능성과 앱 승인 절차.
- 구현:
    1. `ActivityManager`로 현재 실행 중인 태스크 정보 확인.
    2. Activity Recognition API로 사용자 동작(예: 걷기, 정지)도 함께 분석.

여기서 도출된 것들 중 유사한 기능을 다른 유관 부서에서 구현한 것을 보아서 문의 시, UsageStatsManager를 사용하는 것을 알았다. 여기서도 동일한 방법으로 접근해 보기로 결정하였다.

구현하는 코드를 만들어 적용

이를 기반으로 Prompting을 하고 관련된 코드를 입수 하여 독립된 Android App 으로 구현 테스트를 진행한다. 다음과 같은 Prompt를 사용하였다.

너는 android application 개발자야. 다음 요구 사항을 만족하는 application을 만들어줘. 추가적으로 필요한 정보가 있다면, 확인하고 제안해줘. 프로그램을 작성하는 순서를 상세히 설명해줘. 
1. MainActivity를 가지고 있어 
2. MainActivity에는 Start 버튼을 가지고 있어. 이 버튼을 클릭하면, 동작 시간을 측정 시작해. 그리고, Start 버튼이 Stop 버튼으로 변경돼. 
3. MainActivity의 Stop 버턴을 클릭하면, 휴대폰에서 사용자가 다른 어플리케이션을 사용한 내용을 정리해서 알려주는 기능을 가지고 있어. 이 부분은 UsageStatsManager에서 사용 이력을 확인할 수 있어.

이 것 기반으로 Android에서 동작하는 Kotlin 코드를 제공한다. 실제로 Android Studio에 코드를 적용하고, 테스트를 한다. 여기서 획득한 Helper 코드의 기본적인 테스트가 완료되어서, 실재 우리 App과 연동해 보고 동작하는 것을 확인하였다. 

마무리하며

간단한 사례이지만, 여기서 의미 있는 부분은 나의 문제를 명확하게 하고 어떻게 해결할지 고민하면서 필요한 요구 사항을 LLM에게 제공하여 동작 가능한 코드를 제공받았다. 개발자의 학습면에서도 좋다고 생각되는 부분은 제공 받은 코드를 통해서 Kotlin에 대해서 학습할 기회를 얻게 된 부분도 부수적인 장점으로 생각된다.


참고 문헌

[1] https://youtu.be/mzomjCHEPpg?si=TJRR-4Er7arf5m-j
[2] https://youtu.be/IACHfKmZMr8?si=rGTS_SlI96HS16no
[3] https://youtu.be/gKCklJOWB6o?si=N95cuv_Nf23Ar8S8
[4] Modern Anroid Application의 구조 이해, https://technical-leader.tistory.com/174

ViewModel을 사용할 때 Factory를 사용하는 경우와 사용하지 않는 경우에는 큰 차이가 있다. 이 차이를 이해하면, ViewModel의 인스턴스 생성 방식의존성 주입(DI) 활용 방법을 더욱 효과적으로 설계할 수 있다.

1. 기본적인 ViewModel 사용 (Factory 없이)

특징

  • ViewModel이 기본 생성자만 가진 경우 Factory 없이 사용 가능.
  • ViewModelProvider를 사용하여 Activity 또는 Fragment에 간단히 연결 가능.
  • 인수가 필요 없는 ViewModel에 적합.

예제 코드

class MainViewModel : ViewModel() {
    val message = MutableLiveData<String>()
    fun updateMessage(newMessage: String) {
        message.value = newMessage
    }
}

 

class MainFragment : Fragment() {
    private val viewModel: MainViewModel by viewModels()
}

장점

  • 간단하고 구현이 쉬움 (by viewModels() 또는 ViewModelProvider 사용 가능).
  • 생명주기를 고려하여 자동으로 관리됨.

단점

  • 생성자에서 파라미터를 받을 수 없음 (Repository, UseCase 같은 객체를 직접 주입할 수 없음).
  • 의존성 주입(DI)이 어렵고, ViewModel 내부에서 객체를 직접 생성해야 함 (유지보수 어려움).

2. Factory를 사용하는 ViewModel

특징

  • ViewModel 생성자에서 파라미터를 받는 경우 반드시 Factory가 필요함.
  • 보통 Repository, UseCase, API 서비스 등의 객체를 ViewModel에 주입할 때 사용.
  • DI(Dependency Injection) 환경 (예: Hilt, Dagger)에서 활용하기 좋음.

예제 코드

① ViewModel이 생성자를 가지는 경우

class MainViewModel(private val repository: DataRepository) : ViewModel() {
    val data: LiveData<String> = repository.getData()
}

② Custom ViewModelFactory 구현

class MainViewModelFactory(private val repository: DataRepository) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return MainViewModel(repository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

③ Factory를 이용한 ViewModel 생성

class MainFragment : Fragment() {
    private val repository = DataRepository()
    private val viewModel: MainViewModel by viewModels {
        MainViewModelFactory(repository)
    }
}

장점

  • ViewModel의 생성자를 통해 의존성을 주입할 수 있음 (Repository, UseCase 등).
  • DI를 활용하여 테스트가 용이하고 유지보수가 쉬움.

단점

  • Factory 클래스를 따로 구현해야 하므로 코드가 길어질 수 있음.
  • Factory를 생성할 때 ViewModel을 명시적으로 매핑해야 하는 과정이 필요함.

3. Factory를 사용하지 않는 경우 vs Factory를 사용하는 경우 비교

항목Factory 사용 X (by viewModels())Factory 사용 O (Factory 필요)

사용 가능 조건ViewModel에 생성자 파라미터 없음ViewModel에 생성자 파라미터 필요
ViewModel 생성 방식by viewModels() 또는 ViewModelProviderViewModelProvider.Factory를 통해 생성
의존성 주입(DI)불가능 (ViewModel 내부에서 직접 객체 생성)가능 (Repository, UseCase 등 주입 가능)
테스트 용이성어려움 (ViewModel 내부에서 직접 객체 생성)쉬움 (의존성을 모킹(Mock)할 수 있음)
코드의 복잡성단순하고 짧음Factory 클래스를 추가해야 함

4. ViewModelFactory를 활용하는 고급 예제

(1) ViewModel에 여러 개의 의존성을 주입하는 경우

class MainViewModel(
    private val repository: DataRepository,
    private val analyticsTracker: AnalyticsTracker
) : ViewModel() {
    fun logEvent(event: String) {
        analyticsTracker.trackEvent(event)
    }
}

(2) Factory에서 여러 개의 파라미터를 전달

class MainViewModelFactory(
    private val repository: DataRepository,
    private val analyticsTracker: AnalyticsTracker
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return MainViewModel(repository, analyticsTracker) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

(3) Fragment에서 Factory를 활용한 ViewModel 생성

class MainFragment : Fragment() {
    private val repository = DataRepository()
    private val analyticsTracker = AnalyticsTracker()

    private val viewModel: MainViewModel by viewModels {
        MainViewModelFactory(repository, analyticsTracker)
    }
}

5. Hilt를 이용한 ViewModel Factory 대체 방법

최근에는 DI 라이브러리(Hilt, Dagger)를 사용하면 Factory를 직접 구현할 필요 없음.

(1) Hilt를 활용한 ViewModel 생성

① ViewModel에 @HiltViewModel 추가

@HiltViewModel
class MainViewModel @Inject constructor(private val repository: DataRepository) : ViewModel() {
    val data: LiveData<String> = repository.getData()
}

② Repository에 @Inject 추가

class DataRepository @Inject constructor() {
    fun getData(): LiveData<String> {
        return MutableLiveData("Hello from Repository")
    }
}

③ Fragment에서 간단하게 ViewModel 생성

@AndroidEntryPoint
class MainFragment : Fragment() {
    private val viewModel: MainViewModel by viewModels()
}
  • Hilt를 사용하면 Factory 클래스를 직접 만들 필요 없이, 의존성이 자동으로 주입됨.
  • 이 방식이 현재 Android 개발의 표준적인 접근법.

6. 결론

  • ViewModel에 생성자 파라미터가 필요 없다면 Factory 없이 by viewModels() 사용.
  • ViewModel에 생성자 파라미터가 필요하면 반드시 Factory를 사용해야 함.
  • DI 라이브러리(Hilt, Dagger)를 활용하면 Factory 없이도 자동으로 의존성 주입 가능.
  • 테스트 가능성과 유지보수를 고려하면 Factory 또는 Hilt를 사용하는 것이 권장됨.

📌 정리:

간단한 ViewModel → by viewModels()
의존성이 있는 ViewModel → Factory 사용 or Hilt 활용

들어가며..

앞에서 이야기 했던 것[1]과 같이 기존에 개발 중이던 Android Application 과제에 참여하게 되면서 작성된 내용을 이해해야 하는 상황이 되었다. 여기서는 앞에서 언급한 UI 및 네비게이션 흐름 분석 중에서 FragmentTransaction, ViewModel, LiveData의 동작 방식 확인하기 위한 상세 내용에 대해서 살펴 본다.

 

Modern Anroid 구조

(1) Fragment 중심 설계 (Modern Android Architecture)

✅ 장점

  1. 단일 Activity 구조 가능 (Single Activity Architecture)
    • 대부분의 UI를 하나의 Activity에서 관리하고 Fragment를 동적으로 교체.
    • Navigation Component를 활용하면 자연스러운 화면 이동 가능.
  2. 유지보수 및 확장성 용이
    • 같은 Activity 내에서 Fragment만 바꾸면 되므로 화면 재사용성이 높음.
    • 대규모 앱 개발 시 구성 요소를 분리하여 관리하기 용이.
  3. 반응형 UI (Adaptive UI) 지원
    • 태블릿과 스마트폰에 따라 레이아웃을 유연하게 조정 가능.
    • 예: 태블릿에서는 좌측 리스트 + 우측 상세보기, 스마트폰에서는 화면 전환.
  4. Activity 간 전환 비용 감소
    • Activity 간 전환 시 onCreate() → onDestroy() 호출이 발생하여 리소스 소모가 큼.
    • Fragment 전환은 비용이 상대적으로 적고, BackStack을 관리하면 자연스럽게 복귀 가능.
  5. ViewModel과 LifecycleOwner 활용 가능
    • Activity 단위에서 ViewModel을 공유하면 Fragment 간 데이터 유지 가능.
    • viewLifecycleOwner를 활용하면 Fragment의 라이프사이클을 안전하게 관리.

❌ 단점

  1. Fragment의 생명주기 관리가 복잡
    • Activity보다 복잡한 생명주기를 가짐 (onAttach(), onCreateView(), onDestroyView() 등).
    • BackStack을 적절히 관리하지 않으면 메모리 누수 발생 가능.
  2. FragmentTransaction 관리 필요
    • Fragment 간 전환 시 FragmentTransaction을 직접 관리해야 함.
    • commit(), commitNow(), addToBackStack() 등 사용법을 숙지해야 함.
  3. Navigation Component 도입 필요
    • 기존 방식 (FragmentTransaction) 대신 Navigation Component를 사용하는 것이 권장됨.
    • Safe Args 같은 추가적인 학습이 필요할 수 있음.

Fragment vs Activity 사용 비교

Fragment 기반 (Single Activity) - 동적인 화면 변경이 많은 경우
- 데이터 공유가 필요한 경우 (ViewModel 활용)
- 태블릿/멀티-윈도우 지원이 필요한 경우
- Navigation Component를 활용하는 경우
Activity 기반 (Multiple Activity) - 독립적인 기능의 화면이 많고, 서로 연결이 필요 없는 경우
- 단순한 앱(로그인 화면, 설정 화면)에서 사용
- 백스택 관리를 자동으로 하고 싶은 경우

 

Fragment, ViewModel, LiveData 분석 방법

(1) FragmentTransaction 분석

① Fragment 변경 방식 확인

  • replace(), add(), remove(), show(), hide() 사용 여부 확인.
  • commit(), commitNow()의 사용 방식이 적절한지 확인.
  • addToBackStack() 사용 여부 및 Fragment 백스택 관리 방식 파악.

② Fragment 생명주기 확인

  • onCreate(), onCreateView(), onResume(), onPause()의 호출 순서를 Logcat으로 확인.
  • Fragment 간 전환 시 ViewModel이 정상적으로 재사용되는지 확인.

③ Fragment 간 데이터 전달 방식 분석

  • arguments를 통해 전달하는지, ViewModel을 사용하는지 확인.
  • FragmentResultListener 또는 LiveData로 데이터 전달하는지 분석.

(2) ViewModel 분석

① ViewModel 인스턴스 범위 확인

  • Activity 범위인지 Fragment 범위인지 확인 (ViewModelProvider의 owner 확인).
  • Fragment 재생성 시 ViewModel이 유지되는지 확인.

② ViewModel 내부 데이터 흐름 확인

  • LiveData 또는 StateFlow를 사용하여 데이터를 관리하는지 분석.
  • Transformations.map(), Transformations.switchMap()이 적절히 활용되는지 확인.

③ ViewModel의 Clear 시점 분석

  • Fragment가 사라질 때 ViewModel이 정상적으로 유지되는지 또는 제거되는지 확인.

(3) LiveData 동작 분석

① LiveData의 구독 방식 확인

  • observe()가 어디에서 호출되는지 확인 (Activity vs Fragment).
  • viewLifecycleOwner를 사용하고 있는지 확인 (viewLifecycleOwner.lifecycleScope.launchWhenStarted).

② LiveData의 이벤트 처리 방식 확인

  • SingleLiveEvent(일회성 이벤트) vs 일반 MutableLiveData 사용 방식 검토.
  • observeForever()가 사용되었는지 확인 (메모리 누수 가능성 체크).

③ LiveData의 Thread 처리 확인

  • MediatorLiveData 사용 여부 확인 (여러 LiveData 조합 처리 확인).
  • viewModelScope.launch 등을 사용하여 백그라운드에서 처리되는지 확인.

 

마무리

Modern Android Application 구조가 Fragement 기반의 구조로 변경되면서 기존 Android Application을 이해하는 방법도 바뀌었다고 할 수 있다. 즉, Application -> Activity 기반의 구조 이해에서 Fragment, ViewModel, LiveData로 연결되는 구조를 이해를 먼저 해야 한다. 

 

Fragment에서는 변경 방식, 생명주기, 데이터 전달 방식을 이해한 후에, ViewModle 인스턴스 범위 확인, 내부 데이터 흐름 확인 그리고 Clear 시점 분석을 한다. LiveData의 동작 분석에서는 구독 방식, 이벤트 처리 방식, Thread 처리를 확인한다.

 

참고 문헌

[1] Modern Android Application 구조의 이해, https://technical-leader.tistory.com/174

 

들어가며..

기존에 개발 중이던 Android Application 과제에 참여하게 되면서 작성된 내용을 이해해야 하는 상황이 되었다. 일반적으로는 빌드를 해보고, 실행을 해보는 "모의 설치" [1]와 비슷한 절차를 해보았다. 개발 환경을 구축하고 소스를 받아서 빌드를 해보, 소스 코드를 살펴 보았다. 예전에 알고 있던 Android Application과 구조도 많이 달라져 정리해 본다. 특히, LLM과 분석에 대해서 이야기 해볼 때, 여러가지 힌트를 얻어서 기존 Android Application Project를 이해하는데 도움이 될 것으로 보여 정리해 본다.

 

분석 절차

1. 런타임 동작 분석

  • 로그 분석: Logcat을 활용하여 주요 이벤트와 동작 흐름을 분석.
  • 트레이스 프로파일링: Android Profiler를 사용하여 CPU, 메모리, 네트워크 사용 패턴을 확인.
  • StrictMode 활성화: 백그라운드에서 발생하는 블로킹 작업이나 리소스 누수를 감지.

2. 의존성 및 모듈 구조 분석

  • Gradle의 dependencies 확인 (./gradlew dependencies 실행).
  • Android Studio의 Project Structure를 이용하여 모듈 간의 의존성 파악.
  • Dagger/Hilt, Koin 등의 의존성 주입(Dependency Injection) 구조가 있다면 플로우 확인.

3. UI 및 네비게이션 흐름 분석

  • Navigation Component를 사용하고 있다면 nav_graph.xml 분석.
  • Espresso 또는 UI Automator를 이용하여 주요 UI 플로우 자동화 테스트 실행.
  • FragmentTransaction, ViewModel, LiveData의 동작 방식 확인.

4. 네트워크 통신 분석

  • OkHttp 로그 인터셉터 추가하여 API 호출 확인.
  • Charles, Postman, Wireshark를 사용해 실제 API 요청과 응답을 캡처.
  • Retrofit, Volley, Ktor 등의 네트워크 라이브러리 사용 여부 확인.

5. 데이터 저장 방식 분석

  • Room, SharedPreferences, DataStore, Realm 등의 사용 여부 확인.
  • adb shell 명령어를 통해 DB 상태 확인 (adb shell sqlite3 /data/data/your.package.name/databases/your_db_name.db).

6. 멀티스레딩 및 백그라운드 작업 확인

  • WorkManager, JobScheduler, RxJava, Kotlin Coroutines 사용 여부 분석.
  • 주요 백그라운드 태스크 실행 여부와 성능 영향 파악.

7. 앱 보안 및 권한 점검

  • AndroidManifest.xml에서 불필요한 권한이 있는지 확인.
  • 앱의 내부 데이터 보호 방식 (EncrytedSharedPreferences, SQLCipher 등) 점검.
  • ProGuard 또는 R8 난독화 설정 확인.

8. 빌드 및 배포 프로세스 확인

  • CI/CD 파이프라인 (GitHub Actions, Jenkins, Bitrise) 연동 여부 분석.
  • Fastlane 또는 Gradle Task를 활용한 빌드 자동화 방식 점검.

 

정리

위 항목들을 실행하면서 애플리케이션의 구조적 특징과 문제점을 파악할 수 있을 것이다. 특히, 1차적으로 1, 2번은 쉽게 진행하였고 3번을 통해서 전체 프로젝트의 파일들과 역할들을 이해하게 되면서 전체적인 구조의 그림이 보이기 시작했다. 항후 진행 하면서 관련된 배경 지식등을 학습하게 된 내용도 추가 정리해 보자. 

 

참고 문헌

[1] 객체 지향 리엔지니어링 패턴: 3장 첫 번째 접근, https://technical-leader.tistory.com/139

 

 

Waydroid는 Linux 기반의 기기에 Android를 Container로 동작케 한다. WSL을 사용하면 윈도우에서도 Waydroid로 안드로이드 앱을 실행하는 것이 가능하다고 하지만, 아직 권하고 있지 않은 것 같다. 그렇다면, Windows를 유지하면서도 Ubuntu를 설치하고 Waydroid를 설정하는 방법으로 진행해 보자. 리눅스만 설치 되며 쉬운데, 사실 리눅스 설치가 어렵다는 생각이 들었다. 여기서는 포인트와 참고할만한 싸이트를 정리해 두자. 

 

1. Ubuntu 설정

Ubuntu는 현재(2022년 4월) Focal과 Hirsute를 지원한다고 한다. 우선은 설치를 해야 하고, 나는 외장 저장소(혹은 Micro SD를 메모리 형태로 가능)에 설치하는 방법을 정리해 둔다.

 

아래는 추천하지 않는 방법

  1. ISO를 받아 USB로 부탕하여 시도하는 버전: lxc 등 설치가 되지 않고, binder에도 문제가 있어 권하지 않음.
  2. Virtual Machine: 렌더링 성능이 나오지 않아 매우 느림 비추천.
  3. WSL은 시도해 보지 않았지만, 아직 이슈가 많은 듯 (waydroid.io 참고하여 시도해볼지 확인할 것)

 

외장 메모리를 이용하여 Ubuntu 설치하기 위해, ISO로 만든 부팅 USB를 이용하여 부팅을 한다.

Terminal에서 gparted를 이용해서 외장 저장소(메모리 상관없음)를 사용하여 storage와 swap을 잡는다. [1]을 참조하면 된다.

 

관련된 몇가지 이슈가 있었는데 다음 링크를 참조하면 좋겠다.

  1. 검은 화면으로 부팅이 안되는 경우: [2]
  2. UEFI관련 이슈: 다시 설치할 때 부팅이 안되거나 아니면, Ubuntu 삭제시 참고 필요 내용 [3]

 

설치는 되었는데, Ubuntu 부팅을 하지 못하는 경우는 설치 장소를 못 찾는 경우이므로 USB로 외부 저장소를 잡아 볼 수있다. Wifi 안되는 경우도 있었는데, 이 부분은 커널 빌드가 필요하다고 하나, 시도 하지 않았다.

2. Waydroid 설정

Waydroid 설치[4]를 위한 관련 package (curl, lxc, ptyhon3, ca-certificates)를 설치한다.

Ubuntu 버전 (hirsute)를 찾아 아래에서 (bullseye)를 바꾸어 실행한다.

export DISTRO="bullseye" && \
sudo curl -# --proto '=https' --tlsv1.2 -Sf https://repo.waydro.id/waydroid.gpg --output /usr/share/keyrings/waydroid.gpg && \
echo "deb [signed-by=/usr/share/keyrings/waydroid.gpg] https://repo.waydro.id/ $DISTRO main" > ~/waydroid.list && \
sudo mv ~/waydroid.list /etc/apt/sources.list.d/waydroid.list && \
sudo apt update

설치, init 그리고 container를 실행한다.

 

3. App store

F-droid와Aurora가 가능하다고 한다. apk를 받아서 설치한다[5].

waydroid app install xyz.apk

 

4. 총평

Waydroid는 아직 불안하지만, 여러 앱이 동작한다는 부분에서는 충분히 멋지다. 특히, AOSP를 Open Source화 한 LeanageOS의 버전이 올라갈 수록 흥미로운 일일 것으로 보인다.

 

참고내용

[1] [4-2] 외장하드 SSD에 Ubuntu 16.04.1 LTS 설치하기, https://developer-thislee.tistory.com/12

[2] 우분투 USB 설치 블랙스크린 해결, https://arca.live/b/programmers/29170509

[3] 윈도우 EFI 파티션 마운트 및 수정하기, https://blog.djjproject.com/389

[4] Ubuntu/Debian Based Install Instructions, https://docs.waydro.id/usage/install-on-desktops#ubuntu-debian-based-install-instructions

[5] Install and Run Android Applications, https://docs.waydro.id/usage/install-and-run-android-applications

 

 

 

 

+ Recent posts