本文共 10978 字,大约阅读时间需要 36 分钟。
Android Development: Some useful libraries (part I) 你好! 从我自己的经验。 我想出了这个可能最常使用并获得社群批准的库名单(也是谷歌的官方名单)。 您可能不需要为每个应用程序包括所有这些库,但这里的想法是要选择正确的。 支持库 从Google向旧版本的Android提供新的API和稳定性修复程序。 有几个版本,有特定的最低SDK版本,其中一些可以帮助你找到问题,并改进你的代码,如android注释支持: compile 'com.android.support:support-v4:x.y.z' compile 'com.android.support:appcompat-v7:x.y.z' compile 'com.android.support:support-v13:x.y.z' compile 'com.android.support:design:x.y.z' compile 'com.android.support:support-annotations:x.y.z' ... Multidex支持库 如果你曾经遇到超过65k方法错误,而你建立你的应用程序,这可能是你的解决(但这应该是最后的手段,你应该尝试剥离你的应用程序第一):compile 'com.android.support:multidex:x.y.z'
Google Play服务 提供Google提供的各种服务和API,从Google地图到Android Pay,从穿戴式设备到广告。 它是从Google Play商店更新的,因此它的Android操作系统版本是独立的。 要包含在您的项目中: compile 'com.google.android.gms:play-services:x.y.z' 如果你不想包括整个包(因为它是非常大,你可能会遇到超过65k的方法错误),你可以选择性地包括你想要使用的模块: compile 'com.google.android.gms:play-services-wearable:x.y.z' compile 'com.google.android.gms:play-services-maps:x.y.z'...
Retrofit 2 当涉及到实现REST API时,Retrofit仍然是我最喜欢的库。 从他们的网站:“Retrofit将您的REST API变成Java接口。”这是一个优雅的解决方案,用于在项目中组织API调用。 请求方法和相对URL添加了注释,这使代码干净和简单。 使用注释,您可以轻松添加请求正文,操作网址或标题并添加查询参数。 要包括此库,请将其添加到您的build.gradle文件中: compile 'com.squareup.retrofit2:retrofit:2.y.z' compile 'com.squareup.retrofit2:converter-gson:2.y.z'compile 'com.squareup.retrofit2:adapter-rxjava:2.y.z'
这里有一个简单的例子,如何使用Retrofit with RxJava: public interface RestAPI{ @GET(BuildConfig.PATH_TO_MOVIES_SERVICE) Observable<List<Movie>> loadMovies(); // Helper class that sets up new service class Factory { public static RestAPI create() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(BuildConfig.API_BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); return retrofit.create(RestAPI.class); } }RxJava
是Reactive Extensions的Java VM实现,帮助您组合异步,基于事件,类似于代码的流和添加功能编程范例。 这是所有你需要包括这个库: compile 'io.reactivex:rxjava:x.y.z'RxAndroid
包装RxJava库。 它增加了Android特定线程的功能。 注意RxAndroid自动包括一个版本的RxJava。 但是,因为RxAndroid版本是在它后面,如果你想使用最新的RxJava,那么包括两个像: compile 'io.reactivex:rxandroid:x.y.z' compile 'io.reactivex:rxjava:x.y.z' Let’s take an example: private class SomeWebServiceTask extends AsyncTask <String,Result,Void> { protected Result doInBackground(String... someData) { Result result = webService.doSomething(someData); return result; } protected void onPostExecute(Result result) { if (result.isSuccess() { resultText.setText("Hello, world!"); } } } 或者 webService.doSomething(someData) .observeOn(AndroidSchedulers.mainThread()) .subscribe( result -> resultText.setText("Hello, world!"), e -> handleError(e));是啊! 说再见AsyncTasks。
ButterKnife 在每个Android应用程序中,您必须对布局中的每个视图使用findViewById()方法,以便在应用程序的代码中使用。 但是随着应用程序设计的复杂布局,对这个方法的调用变得重复,这就是ButterKnife库所在。 这是所有你需要包括这个库:compile 'com.jakewharton:butterknife:x.y.z'
让我们举个例子。 你最喜欢哪一个? private TextView mFirstNameLabel; private TextView mLastNameLabel; private Button mSubmitButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mFirstNameLabel = (TextView) findViewById(R.id.firstnameLabel); mLastNameLabel = (TextView) findViewById(R.id.lastnameLabel); mSubmitButton = (Button) findViewById(R.id.submitButton); mSubmitButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO call ... } }); } 或者 @Bind(R.id.firstnameLabel) TextView mFirstNameLabel; @Bind(R.id.lastnameLabel) TextView mLastNameLabel; @OnClick(R.id.submitButton) void submit() { // TODO call ... } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); ButterKnife.bind(this); } 第二个代码块使用库,它使用注释通过为您创建样板代码来“绑定”视图。 ButterKnife是小巧,简单,轻量级的,因为它使你的生活作为一个开发人员更容易,你应该几乎总是使用它。 这将是巨大的,如果Android SDK本身可以以这种方式改进! Picasso / Glide Picasso/Glide. 优秀和高效的图像加载库从网络和更多。 但是,在我看来,Glide是现在的最佳选择。 它包含在Google I / O 2014官方应用程序中。 这是所有你需要包括这个库: /** Picasso **/ compile 'com.squareup.picasso:picasso:x.y.z' /** Glide **/ compile 'com.github.bumptech.glide:glide:x.y.z'这篇文章解释了Picasso Glide之间的区别。
这里有一个简单的例子,您可以使用Picasso将图像从URL加载到ImageView中: @Bind(R.id.image_view) ImageView imageView; Picasso.with(this).load(imageUrl).into(imageView);这里有一个简单的例子,您可以使用Glide 将图像从URL加载到ImageView中:
@Bind(R.id.image_view) ImageView imageView; Glide.with(this).load(imageUrl).into(imageView);Timber
是一个轻量级库,可以在不同地方写入日志,并以集中的方式控制它的工作方式。 很容易将其添加为Android Studio项目的依赖项; compile 'com.jakewharton.timber:timber:x.y.z' 典型的日志如下所示: public static String TAG = "ClassName"; ... Log.e(TAG, “A message here”); 但是使用Timber,您可以在应用程序创建中使用类似以下代码: @Override public void onCreate() { super.onCreate(); if (BuildConfig.DEBUG) { Timber.plant(new DebugTree()); } else { Timber.plant(new CrashReportingTree()); } } /** 一个记录崩溃报告重要信息的树。 private static class CrashReportingTree extends Timber.HollowTree { @Override public void i(String message, Object... args) { // TODO e.g., Crashlytics.log(String.format(message, args)); } @Override public void i(Throwable t, String message, Object... args) { i(message, args); // Just add to the log. } @Override public void e(String message, Object... args) { i("ERROR: " + message, args); //Just add to the log. } @Override public void e(Throwable t, String message, Object... args) { e(message, args); // TODO e.g., Crashlytics.logException(t); } } //Timber.i("Message here");
Otto (事件总线) 是一个简化应用程序的不同部分之间的通信的库。 例如,将某个活动从某个活动发送到正在运行的服务,或者在片段之间轻松交互。 要包括它添加到您的gradle: compile 'com.squareup:otto:x.y.z' 以下是我们使用的示例,如果Internet连接丢失,显示如何通知活动: public class NetworkStateReceiver extends BroadcastReceiver { // 如果没有互联网连接,则发生事件 public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); if(intent.getExtras()!=null) { NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO); if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) { // there is Internet connection } else if(intent.getBooleanExtra (ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) { // no Internet connection,send network state changed Bus.post(newNetworkStateChanged(false)); } } // 事件 public class NetworkStateChanged { private mIsInternetConnected; public NetworkStateChanged(boolean isInternetConnected) { this.mIsInternetConnected = isInternetConnected; } public boolean isInternetConnected() { return this.mIsInternetConnected; } } public class MainActivity extends Activity { public static Bus bus; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bus = new Bus(); bus.register(this); // register Otto event Bus } @Override protected void onDestroy() { super.onDestroy(); bus.unregister(this); // unregister Otto event Bus } //Method that will be called when someone posts an event NetworkStateChanged public void onEventMainThread(NetworkStateChanged event) { if (!event.isInternetConnected()) { Toast.makeText(this, "No Internet connection!", Toast.LENGTH_SHORT).show(); } } }正如我先说,Otto(事件总线)允许你直接连接这些类。 你可以有一个事件从类A通知类B与唯一的中介本身。 但是在采用RxJava之后,我认为Rx和事件总线都使用反应模式,而RxJava则更好。 所以我们可以说再见事件总线。 这是一个RxJava作为事件总线的实现:
public class RxBus { private final Subject<Object, Object> bus = new SerializedSubject<>(PublishSubject.create()); public void post(Object o) { bus.onNext(o); } // Subscribe to this Observable. to get it public Observable<Object> getEvents() { return bus; } } // Subscribe to the event getEvents().subscribe(new Action1<Object>() { @Override public void call(Object o) { if(o instanceof AnswerEvent){ // TODO } }});
RetroLambda 这是一种使用Java 8 Lambdas到Java 6/7(以及Android)的方法。 使你的代码更清洁,结合它与RxJava和你是坚实的。 这是所有你需要包括它: classpath 'me.tatarka:gradle-retrolambda:x.y.z' apply plugin: 'me.tatarka.retrolambda' 下面是一个简单的例子如何使用Retrolambda & RxJava Observable.just("Hello, world!") .subscribe(s -> System.out.println(s));是啊! 清洁和简洁的代码。
Dagger 2 Dagger 2是著名的Dagger依赖注入库的继承者,我强烈推荐它。 其中一个主要的改进是在生成的注入代码中使用零反射,这使得调试更容易。 Dagger创建你的类的实例,并满足他们的依赖。 它依赖于javax.inject.Inject注释来标识哪些构造函数或字段应被视为依赖关系。 让我们来看看这个着名的CoffeeMaker示例:class Thermosiphon implements Pump { private final Heater heater; @Inject Thermosiphon(Heater heater) { this.heater = heater; } ... } An example with direct injection into fields: class CoffeeMaker { @Inject Heater heater; @Inject Pump pump; ... } Dependencies are provided via modules and @Provides annotation from Dagger: @Module class DripCoffeeModule { @Provides Heater provideHeater() { return new ElectricHeater(); } @Provides Pump providePump(Thermosiphon pump) { return pump; } } 要使用它添加到build.gradle文件: compile 'com.google.dagger:dagger:x.y.z'compile 'org.glassfish:javax.annotation:10.0-b28'//annotation Dagger compile 'com.google.dagger:dagger-compiler:x.y.z'//Dagger compiler
Realm 是Android中的另一种类型的数据库。 但是,非常重要的是,Realm不使用SQLite。 如果使用ORMLite或ActiveAndroid或任何其他类似的库,您的数据存储在SQLite数据库中,因为这些库给我们在SQLite上只有一个覆盖。 与Realm它是完全不同的是没有SQLite。 这就是你需要使用它:classpath 'io.realm:realm-gradle-plugin:x.y.z' // apply plugin: 'realm-android' 这里有一个非常简单的例子如何使用它: public class Book extends RealmObject { @Required private String title; public String getTitle() { return title; } public void setTitle(final String title) { this.title = title; } } // MAIN_ACTIVITY public class MainActivity extends Activity { private Realm mRealm; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); mRealm = Realm.getInstance(getContext()); } @Override public void onDestroy() { super.onDestroy(); mRealm.close(); } // Example of add/ remove a book @OnClick(R.id.add) public void onAddClick() { mRealm.beginTransaction(); Book book = mRealm.createObject(Book.class); book.setTitle(getTrimTitle()); mRealm.commitTransaction(); } @OnClick(R.id.remove) public void onRemoveClick() { mRealm.beginTransaction(); RealmResults<MyBook> books = mRealm.where(Book.class) .equalTo("title",getTrimTitle()) .findAll(); if(!books.isEmpty()) { for(int i = books.size() - 1; i >= 0; i--) { books.get(i).removeFromRealm(); } } mRealm.commitTransaction(); } private String getTrimTitle() { return mEditTitle.getText().toString().trim(); }}
ViewPropertyAnimator ViewPropertyAnimator在API级别12引入,允许您使用单个Animator实例简单高效地对多个视图属性执行动画操作(并行)。 对我们来说实现程序化是简单和整洁的: // Animate Button mButton.animate() .alpha(1f) .scaleX(1f) .scaleY(1f) .translationZ(10f) .setInterpolator(new FastOutSlowInInterpolator()) .setStartDelay(200) .setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }) .start(); 转换框架 Android转换框架允许您配置应用程序用户界面中的更改的外观。 它提供工具,以有效地管理和导航生活的过渡。 这个框架有一些限制: 应用于SurfaceView的动画可能无法正确显示。 SurfaceView实例从非UI线程更新,因此更新可能与其他视图的动画不同步。 一些特定的过渡类型在应用于TextureView时可能不会产生所需的动画效果。 扩展AdapterView的类(如ListView)以与转换框架不兼容的方式管理其子视图。 如果尝试对基于AdapterView的视图进行动画处理,则设备显示可能会挂起。 如果您尝试使用动画调整TextView的大小,则在对象完全调整大小之前,文本将会弹出到新位置。 要避免此问题,请不要对包含文本的视图的大小调整进行动画处理。转载地址:http://feedi.baihongyu.com/