잘 사용되지 않는 Android 라이브러리에 대한 지나치게 철저한 가이드
게시 됨: 2022-03-11숙련된 개발자라면 누구나 자신이 작성한 코드가 최고의 코드가 아니라고 말할 것입니다. 다른 사람의 작업에서 가져온 코드입니다.
예, 우리 개발자들은 혁신적인 문제 해결사이지만 우리가 직면하는 많은 문제는 이미 해결되었으며 해결 방법은 누구나 사용할 수 있는 라이브러리에 패키지로 제공됩니다. 자유로운 바퀴가 어디에나 있는데 왜 바퀴를 재발명합니까?
안드로이드도 예외는 아니다. 코드 재사용의 궁극적인 소스는 Android SDK 자체로, 많은 작업을 수행할 훌륭한 구성 및 서비스와 함께 제공됩니다.
그러나 SDK가 부족한 경우 Android 커뮤니티는 수많은 코딩 작업을 절약할 수 있는 일부 최고급 라이브러리를 만들어 고도로 조정되고 검증되고 테스트된 구현으로 대체합니다. Android 지원 라이브러리, Android 디자인 지원 라이브러리, Gson과 같은 명백한 라이브러리에 대해 말하는 것이 아닙니다. 나는 당신이 알지 못하는 도구를 언급하고 있습니다. 그리고 사용하더라도 아직 사용하지 않을 것입니다.
저는 수년간 Android 팀을 개발하고 멘토링하고 이끌었으며 수십 개의 외부 도구와 라이브러리를 연구하고 사용했습니다. (나는 심지어 그들의 구현 코드를 읽고 개발자와 내부 논의를 하는 것으로 알려져 있습니다.) 많은 사람들이 내가 작업을 완료하는 데 매우 효과적으로 도움을 주었지만, 사실 대부분은 그렇지 않았습니다.
그래서 이 안내서를 함께 만들었습니다. 내 경험과 다른 모바일 개발자의 경험을 바탕으로 최고의 라이브러리를 사용하고 있는지 확인하십시오. 저는 7개를 골랐습니다. 나는 그들이 곧 당신의 마음에 드는 것 중 일부가 될 것이라고 생각합니다.
올바른 Android 라이브러리 선택
라이브러리를 선택할 때 다음 네 가지 주요 기능을 찾습니다.
- 실제적이고 사소한 문제에 대해 일관되고 고품질의 솔루션을 제공합니다.
- 가능한 한 간단한 API를 사용합니다.
- 내 전체 아키텍처를 강제로 변경하지 않습니다.
- 그것은 많은 사용자 기반을 가지고 있으며 바람직하게는 활발한 개발자 커뮤니티를 보유하고 있습니다.
처음 세 가지 기능은 거래 차단기입니다. 그들이 없으면 계속 진행하거나 수동 코딩을 시작합니다.
아래에서 다루는 라이브러리는 네 가지 테스트를 모두 통과합니다. 또한 모바일 개발의 가장 어려운 측면 중 일부를 해결합니다.
- 의존성 주입을 위한 두 개의 라이브러리, 레이아웃-자바 바인딩, 모의 객체.
- 인앱 게시/구독 메시징 모델입니다.
- 안전하고 효율적인 자가 복구 HTTP 통신 계층.
- 이미지 조작: RAM에 다운로드, 캐싱, 크기 조정 및 로드.
- 실시간 비디오 스트리밍.
- 메모리 누수 감지.
ButterKnife: 궁극적인 의존성 주입 도구
이것은 안드로이드를 위한 궁극적인 의존성 주입 라이브러리입니다. 간단하고 강력하며 매우 빠르며(반사 없음!) 앱의 상용구 코드 를 많이 제거할 수 있습니다.
findViewById()
호출을 통해 각 뷰를 직접 바인딩할 필요가 없습니다. 대신 코드에 직접 액세스할 수 있는 주석 보기가 있습니다. ButterKnife는 또한 onClick
, onTouch
등과 같은 상용구 UI 이벤트의 필요성을 제거하고 자동 삽입 코드로 대체합니다.
하지만 잡담은 충분합니다. 코드를 봅시다.
필드 바인딩 보기:
class MyButterKnifeActivity extends Activity { @BindView(R.id.name) TextView name; @BindView(R.id.address) TextView address; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.bind(this); // MUST BE CALLED BEFORE ACCESSING UI FIELDS name.setText(“etc etc”); } }
리소스 바인딩:
class ExampleActivity extends Activity { @BindString(R.string.username) String username; @BindDrawable(R.drawable.graphic) Drawable graphic; @BindColor(R.color.bg_color) int bgColor; @BindDimen(R.dimen.lower_padding) Float lowerPadding; // and no need for getResources().getString()/getDrawable/getColor() }
UI 이벤트 바인딩:
@OnClick(R.id.my_button) public void clickHandler(View view) { // onClick logic goes here }
AndroidAnnotations: 종속성 주입을 한 단계 더 끌어올리기
종속성 주입과 관련하여 ButterKnife에 가까운 AndroidAnnotations는 약간 다른 접근 방식을 사용합니다. 자동 생성 클래스는 일단 익숙해지면 매우 간단합니다. 훨씬 더 유용한 것은 "이름 기반" 종속성 주입을 허용한다는 것입니다. 예를 들어, @ViewById ListView myUserList;
같은 이름의 layoutListView
와 함께 이 필드를 할당하도록 라이브러리에 지시합니다.
AndroidAnnotations도 매우 빠르지만 ButterKnife와는 다소 다른 방식으로 이를 달성합니다. 런타임 바인딩 종속성 주입 대신 AndroidAnnotations는 영향을 받는 모든 활동의 빌드 시간 복제를 생성하고 연결 논리를 해당 활동에 푸시하므로 손으로 코딩한 논리와 동일한 성능을 얻을 수 있습니다.
그러나 AndroidAnnotations의 주입 기능은 그 이상입니다. 상태와 레이아웃을 모두 활동에 주입할 수 있습니다.
AndroidAnnotations 구현:
@NoTitle @Fullscreen @EActivity(R.layout.my_layout) public class MyActivity extends Activity { @ViewById ListView customerList; // auto-binded to R.id.customerList @App MyApplication app; // auto-binded to app object @AminationRes Animation fadeoutAnimation; @UiThread void updateUI() { // main thread action } }
마지막 주석은 좀 더 설명이 필요합니다. 다중 스레드 Android 앱의 일반적인 작업은 백그라운드(또는 작업자) 스레드에서 UI 구성 요소에 대한 액세스를 허용하는 유일한 스레드로 전환하는 것입니다. . 이 작업은 복잡하지 않지만 종종 필요하며 일부 지저분한 코딩이 포함됩니다.
new Handler(Looper.getMainLooper()).post(new Runnable() { logic goes here } ); // NO ANNOTATIONS
AndroidAnnotations에서 @UiThread를 사용하여 함수에 주석을 추가하기만 하면 됩니다. 이제 항상 실행되도록 보장됩니다.
@UiThread void updateUI() {..} // WITH ANNOTATIONS
이 주석은 표준 Android 구성 요소 클래스(활동, 서비스 등)에 적용됩니다. 하지만 내 클래스에도 주석을 추가하려면 어떻게 해야 합니까?
여기서 AndroidAnnotations는 EBean
의 새로운 개념을 제시합니다. @EBean
을 사용하여 클래스를 표시하기만 하면 됩니다.
@EBean public class MyNonComponentClass { @SystemService NotificationManager notifManager; @Bean MyOtherClass dependency; @UiThread void updateUI() { // main thread work goes here } }
EventBus: 간편한 교차 구성 요소 통신
EventBus 라이브러리는 수년간 Android 개발자를 괴롭혔던 문제를 공원 산책으로 바꿉니다. 구성 요소 간 통신이 그 어느 때보다 간단합니다. 시스템의 두 부분 간에 통신하려면 간단한 게시/구독 모델을 사용하십시오.
백그라운드 폴링 서비스는 더 이상 조각에 변경 이벤트를 제공하기 위해 조각을 인식할 필요가 없습니다.
EventBus 사용법은 간단합니다.
ㅏ. 이벤트 클래스를 만듭니다. 여기에서 POJO로 작업하는 것이 가장 좋습니다.
class NewUserEvent { String fullname; String address; String role; // add getters and setters }
비. 다음 이벤트에 대해 구독하려는 모든 클래스에서 이벤트 처리 메서드를 만듭니다.
class MySubscriber { @Subscribe public void newUserHandler(NewUserEvent event) { // handle NewUserEvent } @Subscribe public void newUserHandler(AnotherEvent event) { // handle AnotherEvent } }
하지만 반쯤 경험이 있는 Android 개발자라면 이 지점에서 멈추고 다음과 같이 묻습니다. 이 핸들러의 스레딩 모델은 무엇입니까? 예를 들어 UI 구성 요소 액세스와 관련된 경우 핸들러가 기본 스레드에서 실행되도록 강제할 수 있습니까? 좋은 질문…
기본적으로 모든 처리기 메서드는 EventBus 자체에서 할당 및 유지 관리하는 스레드 풀에서 가져온 작업자 스레드에서 실행됩니다. 기본 스레드에서 실행할 핸들러 메서드가 필요한 경우 다음과 같이 구독 주석을 확장합니다.
@Subscribe(threadMode = ThreadMode.MAIN) public void runOnMainThreadHandler(AnotherEvent event) { … }
경고: 이 기능을 남용하지 마십시오! 장기 실행 작업은 메인 스레드에서 실행 해서는 안 되며 빠른 작업을 하더라도 주의해야 합니다. 메인 스레드를 압도하는 것은 앱을 느리고 불안정하며 기본적으로 사용자에게 덜 재미 있게 만드는 가장 확실한 방법입니다.
씨. 구독자 클래스의 EventBus 등록 수명 주기를 관리합니다. 즉, 언제 연결되고 버스에서 연결이 끊기나요? 활동에 대한 합리적인 등록 흐름은 다음과 같습니다.
class MySubscriberActivity extends Activity { @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); // START RECEIVING EVENTS HERE } @Override public void onStop() { EventBus.getDefault().unregister(this); // NO MORE EVENTS super.onStop(); } }
물론 위의 내용은 예시일 뿐입니다. 등록(취소)은 원하는 곳 어디에서나 수행할 수 있습니다.
디. 그리고 마지막으로 실제로 이벤트를 발생시킵니다.
EventBus.getDefault().post(new MyEvent(“I'm here”));
EventBus 사용에 대해 알아야 할 것이 훨씬 더 많습니다. 이벤트 멀티캐스팅(기본 동작), 고정 이벤트 사용, 전달 스레드, 우선 순위 등. 그러나 위의 내용으로 간단하면서도 강력한 이 기술을 시작하기에 충분합니다.
OkHttp: 스테로이드의 Android HttpClient
이것이 Android의 HttpClient가 작성되어야 하는 방식입니다. 아주 간단하고 똑똑합니다. OkHttp 라이브러리는 내부적으로 재시도 루프, 페이로드 자동 압축, Http/2 지원, 연결 풀링 및 응답 캐싱을 처리하므로 불필요한 네트워크 액세스를 피할 수 있습니다.
OkHttp 사용법은 간단합니다.
HTTP POST:
OkHttpClient client = new OkHttpClient(); MediaType JSON = MediaType.parse("application/json; charset=utf-8"); RequestBody body = RequestBody.create(JSON, json_str); Request request = new Request.Builder() .url(url) .post(body) .build(); Response response = client.newCall(request).execute(); return response.body().string();
HTTP 가져오기:
OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url(urls[0]) .build(); Response responses = client.newCall(request).execute(); String jsonData = responses.body().string();
OkHttp는 또한 비동기 네트워킹, 요청 리디렉션 경로 쿼리, 로컬 캐시 쿼리 등과 같은 유용한 기능을 지원합니다. 필요한 곳에 자유롭게 사용하세요. 대부분의 개발자는 Android의 기본 HTTP 클라이언트인 HttpURLConnection을 더 스마트하게 대체하기 위해 OkHttp를 사용합니다. 사실 이 전체 프로젝트는 HttpURLConnection을 위한 프라이빗 포크로 시작되었습니다.
그 견고함이 마음에 듭니다. 네트워크 계층에 즉시 추가됩니다.
Picasso: Google에서도 이를 사용하는 데는 이유가 있습니다!
Picasso는 이미지 다운로드, 캐싱, 크기 조정 및 자르기를 관리하는 가장 간단하고 강력한 방법입니다.

이 진술:
Picasso.with(context).load(url).resize(50,50).centerCrop().into(imageView)
당신을 위해 이것을 할 것입니다:
- 원격 URL에 연결합니다.
- 이미지를 다운로드합니다.
- 또한 관리할 로컬 LRU 캐시에 저장합니다.
- 메모리에 로드하기 전에 원본 이미지의 크기를 조정하십시오.
- Picasso가 관리하는 스레드 풀에서 위의 모든 것을 실행하십시오.
- 크기가 조정된 이미지를 사용하여 imageView를 채웁니다.
- 나중에 실행하기 전에 로컬 캐시를 확인하여 네트워크 왕복이 실제로 필요한지 확인하십시오.
위의 작업 세트를 구축하려면 마스터 개발자라도 많은 시간이 소요됩니다. 그리고 그것은 당신이 모든 것을 기억했다고 가정합니다. 크기 조정 부분을 잊었다면 어떻게 될까요?
음, 평균적인 Android 기기에서 앱은 50~60MB 이하의 RAM을 사용하며 대부분의 Android 기기에서 픽셀 대 바이트 비율은 4입니다. 이는 SD 카드에서 13메가픽셀 이미지를 로드하려고 시도한다는 것을 의미합니다. 52MB의 RAM이 필요합니다. 즉, 앱이 즉시 중단됩니다.
이것은 피카소의 힘의 한 예일 뿐입니다. 미디어 집약적인 레거시 프로젝트를 최적화/디버깅할 때 내가 가장 먼저 하는 일 중 하나는 모든 이미지 로딩을 Picasso로 전환하는 것입니다. 이 간단한 단계가 앱 품질에 미치는 영향에 놀랄 것입니다.
이 라이브러리의 강력함에 대한 가장 강력한 증거 중 하나: 지난 2년 동안 Google의 자체 Android 코드 샘플 중 많은 부분이 이미지 로드에 Picasso를 사용합니다.
ActiveAndroid: ORM에서 성능 오버헤드 제거
Object Relational mapping의 줄임말인 ORM은 J2EE 시대에 대중화되었습니다. 이를 통해 POJO를 별도의 필드로 변환할 필요 없이 데이터베이스에 저장하고 데이터베이스에서 검색할 수 있습니다.
도움이 되나요? SQL 문을 코딩하지 않고도 앱의 많은 부분을 작성할 수 있기 때문입니다.
또한 매우 효율적입니다. 예전에 ORM 플랫폼은 리플렉션에 크게 의존했고 느리기로 악명이 높았습니다. ActiveAndroid를 포함한 최신 플랫폼은 훨씬 빠르며 대부분의 실제 요구 사항에 대해 원시 SQL 코딩에 비해 성능 오버헤드가 발생하지 않습니다.
용법:
ㅏ. 사용자 정의 Application 클래스를 확장하여 애플리케이션 객체에서 초기화:
public class MyApplication extends extends com.activeandroid.app.Application { … }
비. 데이터베이스에 저장하려는 각 레코드에 대한 클래스를 사용하여 모델 클래스에 대해 파생된 POJO를 작성하십시오. 이러한 각 POJO는 자체 테이블에 상주할 수 있습니다. 주석은 저장된 각 멤버에 대한 DB 필드의 이름을 지정하는 데 사용해야 합니다.
@Table(name = "Categories") public class UserDetails extends Model { @Column(name = "Name") public String name; @Column(name = "Address") public String address; @Column(name = "Age") public int age; }
멤버에 대한 인덱스를 설정하려면 다음 주석을 사용하십시오.
@Column(name = "ID", index = true) public String userID;
씨. 라이브러리가 기본 동작인 가장 고급스러운 시작 시간 전체에 걸쳐 반복되는 것을 방지하려면 다음 매니페스트 섹션에서 모든 모델 클래스를 지정하는 것이 좋습니다.
<meta-data android:name="AA_MODELS" android:value=“com.myapp.MyModelA, com.myapp.MyModelB" />
참고: 이 목록에 나타나지 않는 모델 클래스는 ActiveAndroid에서 인식되지 않습니다.
디. 데이터베이스에 쓰기:
UserDetails usr = new UserDetails(); usr.save(); // RUNS ON A BACKGROUND THREAD
여러 쓰기가 필요한 경우 더 효율적인 방법은 단일 트랜잭션에서 일괄 처리하는 것입니다.
ActiveAndroid.beginTransaction(); try { for (UserDetails u: userList) item.save(); ActiveAndroid.setTransactionSuccessful(); } finally { ActiveAndroid.endTransaction(); }
이자형. 데이터베이스에서 POJO 읽기:
new Select() .from(UserDetails.class) .where("name = ?", usr.getName()) .orderBy("Age") .executeSingle();
ORM은 제가 서버 측 개발자로 일하던 시절에 꼭 필요한 도구였습니다. Android 도메인에 다소 늦게 진입했습니다. 그러나 마침내 여기에 있습니다. 데이터베이스 프로그래밍은 가능한 한 간단합니다. 즐기세요.
LibStreaming: 고통 없는 비디오 스트리밍
실시간 비디오 스트리밍은 문서화되지 않은 API, 크로스 SDK 버전 차이, 반사 사용 등으로 인해 큰 골칫거리였습니다.
운 좋게도 libStreaming은 스트리밍 복잡성의 대부분을 캡슐화하고 몇 시간 만에 기본 스트리밍 앱을 작성할 수 있는 간단하고 친숙한 API를 노출하여 이 모든 것을 변경했습니다.
H.264 및 AAC에 사용하려면 다음을 수행해야 합니다.
ㅏ. 주 활동의 onCreate 메소드에서 세션 객체를 초기화합니다. 세션 개체는 피어로 스트리밍되는 미디어를 나타냅니다.
protected void onCreate(Bundle savedInstanceState) { mSession = SessionBuilder.getInstance() .setCallback(this) .setSurfaceView(mSurfaceView) .setPreviewOrientation(90) .setContext(getApplicationContext()) .setAudioEncoder(SessionBuilder.AUDIO_NONE) .setAudioQuality(new AudioQuality(16000, 32000)) .setVideoEncoder(SessionBuilder.VIDEO_H264) .setVideoQuality(new VideoQuality(320,240,20,500000)) .build(); mSurfaceView.getHolder().addCallback(this); }
비. 실제로 세션을 시작하십시오.
mSession.setDestination(destination_server_url); mSession.start();
씨. 완료되면 세션을 중지합니다.
mSession.stop();
이제 오해하지 마시기 바랍니다. 실시간 스트리밍은 본질적으로 지저분하며 libStreaming은 이러한 복잡성을 제거하지 않습니다. 그러나 대부분의 시간에 그것을 숨기는 것은 정말 좋은 일입니다. 경우에 따라 피어 신호 정책 선택, 카메라 인코딩 선택(일반적으로 MediaCodec/표면 대 버퍼 사용) 또는 패킷화 처리와 같은 복잡성을 처리해야 합니다.
그럼에도 불구하고 libStreaming 뒤에 있는 좋은 사람들이 이러한 복잡성을 사용하기 쉬운 API로 매끄럽게 병합하는 데 추가 노력을 기울였음을 알게 될 것입니다.
LibStreaming은 H.264, H.263, AAC 및 AMR을 포함하여 Android 앱에서 사용하는 대부분의 인코더를 지원합니다.
나는 이 라이브러리로 훌륭한 결과를 얻었습니다. 가장 인기 있는 스트리밍 앱 중 일부는 이를 인프라의 일부로 사용합니다. 필요한 경우 미디어 스트리밍 경험을 훨씬 더 원활하게 만들 것이라고 확신합니다.
LeakCanary: 코드 줄에서 메모리 누수 감지
이 라이브러리의 동기인 메모리 누수 부터 시작하겠습니다. Android 앱은 특히 코딩에 주의하지 않는 경우 이러한 경향이 있습니다. 사실, 메모리 누수를 만드는 것은 매우 간단합니다. 컨텍스트 외부에 활동 참조를 저장하기만 하면 됩니다. 사실, 액티비티 컨텍스트 외부에 단일 뷰 객체에 대한 참조를 저장하더라도 누수가 발생합니다.
왜요? 보기(사실상 모든 보기)는 포함하는 활동에 대한 컨텍스트 참조를 내부적으로 저장하기 때문입니다. 뷰에 대한 참조가 유지되는 한 드로어블, 뷰 계층 구조 및 리소스를 포함하여 뷰 내부의 내용과 함께 뷰에 포함된 활동은 가비지 수집기가 회수할 수 없습니다.
누출 활동에 대한 참조를 유지하는 것이 정적 매개변수로 항상 명확한 것은 아닙니다. 내부 클래스를 생성하거나 활동 내부에 스레드를 생성할 때마다 해당 활동에 대한 참조가 생성되고 해당 내부 클래스 또는 스레드가 완료될 때까지 활동이 회수되지 않을 수 있습니다.
단일 리소스 집약적 활동에 대한 참조를 누출하는 것만으로도 " 메모리 부족 " 예외와 함께 앱이 충돌하는 경우가 있습니다.
어떻게 그들로부터 보호할 수 있습니까? 물론 엄격한 코딩 관행 부터 시작하십시오. 그러나 우리 모두가 경험 많은 Android 개발자는 아니며 경험 많은 개발자조차도 때때로 규칙을 잊어버립니다.
메모리 누수에 중점을 둔 정기적인 코드 검토가 도움이 될 수 있지만 시간이 걸립니다. 또한 일부 누출은 실제로 교활하고 단순한 코드 검토로 감지하기 어렵습니다.
DDMS의 메모리 도구를 사용하면 시간이 지남에 따라 앱이 누출되는지 여부를 알 수 있습니다. 반드시 사용하셔야 합니다. 그러나 누출의 원인이 무엇인지는 알려주지 않습니다.
여기서 leakCanary가 구출됩니다. 현존하는 최고의 메모리 누수 감지기이며, 한 두 줄의 코드처럼 모든 활동에 대한 누수 감지 기능을 자동으로 제공합니다.
이를 사용하려면 앱의 객체 onCreate()
로 leakCanary를 초기화하기만 하면 됩니다.
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); LeakCanary.install(this); // more initialisations } }
그리고 당신은 끝났습니다. LeakCanary는 메모리 누수를 모니터링하고 감지하면 알림을 보냅니다.
LeakCanary는 ActivityRefWatcher
라는 객체를 모든 활동에 자동 주입하고 onDestroy()
가 호출된 후 해당 참조 수를 모니터링하여 이 마법을 달성합니다. 파괴된 활동에 대한 > 0 참조 카운트는 누출을 의미할 수 있습니다.
중요: 누출 감지는 디버그 모드 애플리케이션에서만 작동합니다. 릴리스 모드 APK에서 누출을 테스트하지 마십시오(LeakCanary가 아니라).
그러나 누출에 대해 시스템의 다른 부분을 테스트하려면 어떻게 해야 합니까? 여기에서 LeakCanary는 refWatcher라는 객체를 제공하며, 이는 실제로 초기화 호출의 반환 값입니다.
refWatcher = LeakCanary.install(this);
곧 회수될 값을 확인하는 데 사용할 수 있습니다. 더 정확히 말하면, 내가 생각하는 가치는 곧 회복될 것입니다. 그렇게 하려면 다음으로 전화하십시오.
refWatcher.watch(my_soon_to_be_reclaimed_obj);
이 객체가 watch 호출 후 짧은 시간 동안 해제되지 않은 경우 라이브러리에서 알려줍니다.
나는 이 "짧은 시간"의 가치를 어디에서도 찾을 수 없었지만 아마도 그렇게 중요하지 않을 것입니다. leakCanary를 사용하면 모든 것이 제대로 작동합니다. 아주 재미있는.
요약
숙련된 개발자는 이러한 라이브러리를 사용하여 코딩 및 디버깅 단계에서 며칠 및 몇 주를 단축하므로 동일한 작업을 수행하지 못할 이유가 없습니다.
요약하자면, 제가 선택한 Android 라이브러리는 다음과 같습니다.
ButterKnife – 자동 삽입 코드는 앱의 상용구 코드를 제거하는 데 도움이 됩니다. Android를 위한 최고의 코드 주입입니다. 더 말이 필요합니까?
AndroidAnnotations – 눈부시게 빠른 자동 생성 클래스와 이름 기반 코드 삽입을 사용하여 손으로 코딩한 로직에 비해 성능 저하 없이 시간을 절약할 수 있습니다.
EventBus – 보다 강력한 코드를 위해 구성 요소를 분리하고 구성 요소 간 통신이 그 어느 때보다 간단합니다.
OkHttp – 비동기 네트워킹, 요청 리디렉션 경로 쿼리, 로컬 캐시 쿼리 등을 지원하여 HttpURLConnection을 대체합니다.
Picasso – 간소화된 이미지 조작이 매우 우수하여 현재 Google에서 사용하고 있습니다. 미디어 사용량이 많은 프로젝트 및 특정 레거시 프로젝트에서 시간을 크게 절약할 수 있습니다.
ActiveAndroid – 성능 오버헤드 없이 ORM이 쉬워졌습니다.
LibStreaming – 주요 스트리밍 앱에서 사용하는 실시간 비디오 스트리밍.
시간을 할애할 가치가 있는 유일한 Android 라이브러리입니까? 확실히. 그러나 나는 이것을 약속합니다. 다음 프로젝트에서 이들 중 하나를 사용하면 훨씬 더 나은 개발자가 될 것입니다. 작동하는 모습을 보고 싶다면 내 GitHub를 살펴보세요.
이미 일부 또는 전체를 사용하고 있거나 대체 라이브러리를 사용 중인 경우 아래 의견에서 경험을 공유할 것을 촉구합니다.