Java tutorial
/* * The MIT License (MIT) * * Copyright (c) 2015 malin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.malin.rxjava.activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.jakewharton.rxbinding.view.RxView; import com.jakewharton.rxbinding.widget.RxTextView; import com.jakewharton.rxbinding.widget.TextViewTextChangeEvent; import com.malin.rxjava.R; import com.malin.rxjava.application.RxJavaApplication; import com.malin.rxjava.constant.Constant; import com.malin.rxjava.factory.DataFactory; import com.malin.rxjava.factory.ImageNameFactory; import com.malin.rxjava.githubapi.GitHubApi; import com.malin.rxjava.model.Contributor; import com.malin.rxjava.model.Course; import com.malin.rxjava.model.Student; import com.malin.rxjava.model.User; import com.malin.rxjava.service.RetrofitService; import com.malin.rxjava.utils.ClickUtils; import com.malin.rxjava.utils.DeviceInfo; import com.malin.rxjava.utils.ImageUtils; import com.malin.rxjava.utils.RecycleBitmap; import com.malin.rxjava.utils.RxUtils; import com.malin.rxjava.utils.ToastUtil; import com.orhanobut.logger.LogLevel; import com.orhanobut.logger.Logger; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import rx.Observable; import rx.Observer; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action0; import rx.functions.Action1; import rx.functions.Func1; import rx.schedulers.Schedulers; import rx.subscriptions.CompositeSubscription; /** * ??:? * :malin.myemail@gmail.com * :15-11-10. * : */ public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private static final String TAG_FOR_LOGGER = "MainActivity_I_LOVE_RXJAVA"; private static final String ERROR = "??"; private static final String JPG = ".jpg"; private int mCounter;// private ImageView mImageView; private Bitmap mManyBitmapSuperposition = null; private Canvas mCanvas = null; private ProgressBar mProgressBar; private EditText mSearchEditText; private TextView mResultTextView; private Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initializeLogAndDeviceInfo(); initView(); initData(); testFuncation(9);//RxJava } /** * ?Logger??? */ private void initializeLogAndDeviceInfo() { Logger.init(TAG_FOR_LOGGER).logLevel(LogLevel.FULL);//Use LogLevel.NONE for the release versions. DeviceInfo.getInstance().initializeScreenInfo(this); } /** * ? */ private void initView() { mContext = this; mImageView = (ImageView) findViewById(R.id.iv_image); mResultTextView = (TextView) findViewById(R.id.tv_result); mSearchEditText = (EditText) findViewById(R.id.ed_search); mProgressBar = (ProgressBar) findViewById(R.id.progressbar); } private void initData() { mContext = this; } /** * ??,?? */ private void getException() { int errorCode = Integer.valueOf(ERROR); } //-----------------------------------------------0:RxJava----------------------------------------------------------- // //1:,?:??? //2::? //3: private void method0() { //1:,? //:RxJava Observable.create() ? Observable ? Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("Hello"); subscriber.onNext("World"); subscriber.onNext("!"); subscriber.onCompleted(); subscriber.onError(new Throwable()); Logger.d("-observable->call()->onCompleted()??"); } }); /** * ? OnSubscribe ? * OnSubscribe Observable * Observable OnSubscribe call() ???? * ??subscriber onNext() onCompleted() * ??? */ //2: Observer<String> observer = new Observer<String>() { @Override public void onCompleted() { Logger.d("-observer:onCompleted()"); } @Override public void onError(Throwable e) { Logger.d("-observer:onError" + e.getMessage()); } @Override public void onNext(String s) { Logger.d("-observer:onNext():" + s); // getException();//??,onError().... } }; //3:-- observable.subscribe(observer); } //---------------------------------------1:? Observable.just(T...)-------------------------------------------------------------- // create() RxJava ? RxJava ???? // just(T...): ?????. //:,RxJava?:just(T...): /** * : * {@link #method0()} */ private void method1() { // //1:: //2:: //3:- //1:: //just(T...): ????? Observable<String> observable = Observable.just("Hello", "World", "!"); // ? // onNext("Hello"); // onNext("World"); // onNext("!"); // onCompleted(); //2:: Observer<String> observer = new Observer<String>() { @Override public void onCompleted() { Logger.d("-observer:onCompleted()"); } @Override public void onError(Throwable e) { Logger.d("-observer:onError()"); } @Override public void onNext(String s) { Logger.d("-observer:onNext():" + s); //getException();//??,onError().... } }; //3:: observable.subscribe(observer); } //---------------------------------------2:? Observable.from(T[]) / from(Iterable<? extends T>-------------------------------------------------------------- /** * :: RxJava?:just(String[] array) Iterable ?????? * {@link #method1()} */ private void method2() { // //1: //2: //3:- String[] array = new String[] { "Hello", "World", "!" }; //1:: //just(String[] array) Iterable ?????? Observable observable = Observable.from(array); // ? // onNext("Hello"); // onNext("World"); // onNext("!"); // onCompleted(); //2: Observer observer = new Observer() { @Override public void onCompleted() { Logger.d("-observer:onCompleted()"); } @Override public void onError(Throwable e) { Logger.d("-observer:onError()"); } @Override public void onNext(Object o) { String str = (String) o; Logger.d("-observer:onNext():" + str); // getException();//??,onError().... } }; //3:: observable.subscribe(observer); } //---------------------------------------3: subscribe()??-------------------------------------------------------------- /** * * {@link #method2()} * subscribe?? * subscribe(final Action1<? super T> onNext) */ private void method3() { String[] array = new String[] { "Hello", "World", "!" }; //1: Observable observable = Observable.from(array); //2: Action1 onNextAction = new Action1() { @Override public void call(Object o) { String str = (String) o; Logger.d(":call(Object o):" + str); } }; //3:- //subscribe(final Action1<? super T> onNext) // Subscriber onNextAction ? onNext() observable.subscribe(onNextAction); } /** * * subscribe?? * {@link #method3()} * subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError) */ private void method4() { //1: Observable observable = Observable.from(new String[] { "Hello", "World", "!" }); //2: Action1 onNextAction = new Action1() { @Override public void call(Object o) { String str = (String) o; Logger.d(":onNextAction:call(Object o):o:" + str); } }; Action1<Throwable> onErrorAction = new Action1<Throwable>() { @Override public void call(Throwable throwable) { Logger.d(":onErrorAction:call(Throwable throwable):" + throwable.getMessage()); } }; //3: //subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError) // Subscriber onNextAction onErrorAction ? onNext() onError() observable.subscribe(onNextAction, onErrorAction); } /** * subscribe?? * subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onComplete) */ private void method5() { //1: Observable observable = Observable.from(new String[] { "Hello", "World", "!" }); //2: Action1 onNextAction = new Action1() { @Override public void call(Object o) { String str = (String) o; Logger.d(":onNextAction:call():s:" + str); } }; Action1<Throwable> onErrorAction = new Action1<Throwable>() { @Override public void call(Throwable throwable) { Logger.d(":onErrorAction:call(Throwable throwable):" + throwable.getMessage()); } }; Action0 onCompletedAction = new Action0() { @Override public void call() { Logger.d(":onCompletedAction:call()"); } }; //3:: //subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onComplete) // Subscriber onNextAction? onErrorAction onCompletedAction ? onNext()? onError() onCompleted() observable.subscribe(onNextAction, onErrorAction, onCompletedAction); } //---------------------------------------4: Action0Action1 -------------------------------------------------------------- /** * ?Action0Action1,???; * ??: * * MaLin:,Action0Action1,??? * * :,?: * Action0 RxJava ?? call()? * onCompleted() ? Action0 ?? * onCompleted() ?? subscribe() ? * ?? onCompleted() ? subscribe()?? * * Action1 ??? call(T param)? * Action0 ?? onNext(T obj) onError(Throwable error) ?? * Action1 ? onNext(obj) onError(error) ? subscribe() ? * Action0 Action1 API RxJava ?? ActionX ?? ( Action2, Action3) * ??? */ //---------------------------------------5: ?!??------------------------------------------------------------- //1.[logger](https://github.com/orhanobut/logger) | ?,,Android //2.[pidcat](https://github.com/JakeWharton/pidcat)|JakeWharton?,,|? /** * com.github.orhanobut:logger ?? * ???????????????????????????????????????????????????????????????????????????????????????? D Thread: main D D MainActivity$11.onNext (MainActivity.java:338) D MainActivity$11.onNext (MainActivity.java:354) D D onNext() D ???????????????????????????????????????????????????????????????????????????????????????? D ???????????????????????????????????????????????????????????????????????????????????????? D Thread: main D D SafeSubscriber.onCompleted (SafeSubscriber.java:83) D MainActivity$11.onCompleted (MainActivity.java:341) D D onCompleted() D ???????????????????????????????????????????????????????????????????????????????????????? */ //---------------------------------------6 -Scheduler------------------------------------------------------------- /** * * ???? * ? IO ?????????? */ private void method6() { final int drawableRes = R.mipmap.malin; Observable.create(new Observable.OnSubscribe<Drawable>() { //1: @Override public void call(Subscriber<? super Drawable> subscriber) { Logger.d(""); Drawable drawable = ContextCompat.getDrawable(RxJavaApplication.getApplication(), drawableRes); subscriber.onNext(drawable); subscriber.onCompleted(); } }).subscribeOn(Schedulers.io())// subscribe() ? IO // doOnSubscribe() ? observeOn() ? observeOn() .doOnSubscribe(new Action0() { @Override public void call() { if (mProgressBar != null) { mProgressBar.setVisibility(View.VISIBLE);//ProgressBar--? } } }).observeOn(AndroidSchedulers.mainThread())// Subscriber ??? .subscribe(new Subscriber<Drawable>() { //3: //2: @Override public void onCompleted() { if (mProgressBar != null) { mProgressBar.setVisibility(View.GONE); } Logger.d(" onCompleted()"); Toast.makeText(MainActivity.this, " onCompleted()", Toast.LENGTH_SHORT).show(); } @Override public void onError(Throwable e) { if (mProgressBar != null) { mProgressBar.setVisibility(View.GONE); } Logger.d(" onError()"); Toast.makeText(MainActivity.this, " onError() " + e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override public void onNext(Drawable drawable) { Toast.makeText(MainActivity.this, " onNext()", Toast.LENGTH_SHORT).show(); Logger.d(" onNext()"); if (mImageView == null || drawable == null) return; mImageView.setImageDrawable(drawable); } }); } //---------------------------------------7: ?? map()------------------------------------------------------------- private void method7() { final int drawableRes = R.mipmap.malin; //1: Observable.just(drawableRes)// int .map(new Func1<Integer, Drawable>() { @Override public Drawable call(Integer integer) {// ? String Logger.d("integer:" + integer); return ContextCompat.getDrawable(RxJavaApplication.getApplication(), integer); } }).subscribeOn(Schedulers.io())// subscribe() ? IO //doOnSubscribe() ? observeOn() ? observeOn() .doOnSubscribe(new Action0() { @Override public void call() { if (mProgressBar != null) { mProgressBar.setVisibility(View.VISIBLE);//ProgressBar--? } } }).observeOn(AndroidSchedulers.mainThread())// Subscriber ??? .subscribe(new Subscriber<Drawable>() { //3: //2: @Override public void onCompleted() { if (mProgressBar != null) { mProgressBar.setVisibility(View.GONE); } Logger.d(":onCompleted()"); } @Override public void onError(Throwable e) { if (mProgressBar != null) { mProgressBar.setVisibility(View.GONE); } Toast.makeText(MainActivity.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show(); Logger.d(":onError(Throwable e):" + e.getMessage()); } @Override public void onNext(Drawable drawable) { if (mImageView == null || drawable == null) return; mImageView.setImageDrawable(drawable); Logger.d(":onNext(Drawable drawable):" + drawable.toString()); } }); } //---------------------------------------8: ?------------------------------------------------------------- // private void method8() { ArrayList<Student> students = DataFactory.getData(); int size = students.size(); for (int i = 0; i < size; i++) { Logger.d("??:" + students.get(i).name); int sizeCourses = students.get(i).courses.size(); for (int j = 0; j < sizeCourses; j++) { Logger.d(":" + students.get(i).courses.get(j).name); } } } /** * ?:???:?()?? * RxJava: * {@link #method8()} */ private void method9() { //just(T...): ?????,?? Observable.from(DataFactory.getData()).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Student>() { @Override public void call(Student student) { Logger.d(":" + student.name); } }); } /** * ?:??:?(??)?? * RxJava * {@link #method9()} */ private void method10() { //1: //2:?? //3: //4: //5: //6: Observable.from(DataFactory.getData()) .map(new Func1<Student, String>() { @Override public String call(Student student) { return student.name; } }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<String>() { @Override public void onCompleted() { Logger.d(":onCompleted()"); } @Override public void onError(Throwable e) { Logger.d(":onError(Throwable e) " + e.getMessage()); } @Override public void onNext(String s) { Logger.d(":onNext(String s) " + s); } }); } /** * ?:??:?(??)??,method9() * RxJava * ?? * {@link #method10()} */ private void method11() { Observable.from(DataFactory.getData()).map(new Func1<Student, String>() { @Override public String call(Student student) { return student.name; } }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<String>() { @Override public void call(String s) { Logger.d(":" + s); } }); } //---------------------------------------9: flatmap()------------------------------------------------------------- /** * ?:? * RxJava * ? * {@link #method11()} */ private void method12() { //1: //2: //3: Observable.from(DataFactory.getData()).subscribe(new Subscriber<Student>() { @Override public void onCompleted() { Logger.d(":onCompleted()"); } @Override public void onError(Throwable e) { Logger.d(":onError(Throwable e)" + e.getMessage()); } @Override public void onNext(Student student) { ArrayList<Course> courses = student.courses; for (Course course : courses) { Logger.d(":" + course.name); } } }); } /** * ?:?,method12 * RxJava * {@link #method12()} * Student->ArrayList<Course> */ private void method13() { Observable.from(DataFactory.getData()) .map(new Func1<Student, ArrayList<Course>>() { @Override public ArrayList<Course> call(Student student) { return student.courses; } }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<ArrayList<Course>>() { @Override public void call(ArrayList<Course> courses) { for (int i = 0; i < courses.size(); i++) { Logger.d(":" + courses.get(i).name); } } }); } //---------------------------------------10: flatMap()------------------------------------------------------------- /** * ?:?,method13 * RxJava * {@link #method13()} * Student -> ArrayList<Course> -> Observable<Course> -> */ private void method14() { //1: //2:?? //3: //4: //5: //6: // Student->Course Observable.from(DataFactory.getData()).flatMap(new Func1<Student, Observable<Course>>() { @Override public Observable<Course> call(Student student) { return Observable.from(student.courses); } }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Course>() { @Override public void call(Course course) { Logger.d(":" + course.name); } }); } //---------------------------------------10: RxBinding------------------------------------------------------------- /** * ?,. */ private void method15() { mImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { runOnUiThread(new Runnable() { @Override public void run() { if (ClickUtils.isFastDoubleClick()) { ToastUtil.getInstance().showToast(MainActivity.this, ""); return; } ToastUtil.getInstance().showToast(MainActivity.this, "??click"); } }); } }); } /** * RxBinding * RxBinding Jake Wharton ??? Android ? RxJava Binding API * Binding OnClickListener ? TextWatcher API * ?? RxBinding ??? * throttleFirst() */ private void method16() { RxView.clicks(mImageView).throttleFirst(500, TimeUnit.MILLISECONDS)//500ms,?,500ms,500ms??? .subscribeOn(AndroidSchedulers.mainThread()).observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Void>() { @Override public void call(Void aVoid) { Toast.makeText(MainActivity.this, "click", Toast.LENGTH_SHORT).show(); } }); } /** * RxBinding */ private void method17() { RxView.longClicks(mImageView).throttleFirst(500, TimeUnit.MILLISECONDS).subscribe(new Action1<Void>() { @Override public void call(Void aVoid) { Toast.makeText(MainActivity.this, "long click", Toast.LENGTH_SHORT).show(); } }); } /** * EditText,?500ms,?? */ private void method18() { mSearchEditText.setVisibility(View.VISIBLE); RxTextView.textChangeEvents(mSearchEditText).debounce(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<TextViewTextChangeEvent>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(TextViewTextChangeEvent textViewTextChangeEvent) { String changedMessage = textViewTextChangeEvent.text().toString(); Logger.d(TAG, changedMessage); if (!TextUtils.isEmpty(changedMessage)) { ToastUtil.getInstance().showToast(MainActivity.this, changedMessage); } } }); } /** * ?Defer?Just */ //?? Range???nm?nm //::1,2,3,4,5 // ????Subscriber private void method19() { Observable.range(1, 5).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { Logger.d(integer.toString() + ""); } }); } /** * Retrofit,?androidmalinGitHub? */ private void method21() { mProgressBar.setVisibility(View.VISIBLE); mImageView.setVisibility(View.GONE); mResultTextView.setVisibility(View.VISIBLE); mResultTextView.setText(""); Call call = RetrofitService.getInstance().createService(GitHubApi.class).getUser("androidmalin"); //asynchronous call.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { User user = (User) response.body(); if (user == null) { //404 or the response cannot be converted to User. ResponseBody responseBody = response.errorBody(); if (responseBody != null) { try { Logger.d("responseBody = " + responseBody.string()); mResultTextView.setText("responseBody = " + responseBody.string()); } catch (IOException e) { e.printStackTrace(); } } else { Logger.d("responseBody = null"); mResultTextView.setText("responseBody = null"); } } else { //200 String message = "Github Name :" + user.name + "\nWebsite :" + user.blog + "\nCompany Name :" + user.company; ToastUtil.getInstance().showToast(MainActivity.this, message); Logger.d(message); mResultTextView.setText(message); } mProgressBar.setVisibility(View.GONE); } @Override public void onFailure(Call<User> call, Throwable t) { Logger.d("t = " + t.getMessage()); mProgressBar.setVisibility(View.GONE); } }); } /** * Retrofit,?RxJava ?androidmalinGitHub? */ private void method22() { //TODO:1:,?? //TODO:2: //TODO:3:, Observable<User> observable = RetrofitService.getInstance().createService(GitHubApi.class) .getUserObservable("androidmalin"); observable.subscribeOn(Schedulers.io()).doOnSubscribe(new Action0() { @Override public void call() { mProgressBar.setVisibility(View.VISIBLE); mResultTextView.setText(""); mImageView.setVisibility(View.GONE); mResultTextView.setVisibility(View.VISIBLE); } }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<User>() { @Override public void onCompleted() { Logger.d("onCompleted()"); mProgressBar.setVisibility(View.INVISIBLE); Toast.makeText(MainActivity.this, "onCompleted", Toast.LENGTH_SHORT).show(); } @Override public void onError(Throwable e) { Logger.d("onError()=>" + e.getMessage()); } @Override public void onNext(User user) { Logger.d("onNext()"); String message = "Github Name :" + user.name + "\nWebsite :" + user.blog + "\nCompany Name :" + user.company; Toast.makeText(MainActivity.this, "onNext", Toast.LENGTH_SHORT).show(); Logger.d(message); mResultTextView.setText(user.toString()); } }); } private ArrayAdapter<String> mAdapter; private CompositeSubscription mSubscription = new CompositeSubscription(); private ListView mResultListView; /** * Retrofit,?RxJava ?square?retrofit */ private void method23() { mImageView.setVisibility(View.GONE); mResultTextView.setVisibility(View.GONE); mImageView.setVisibility(View.GONE); mResultListView = (ListView) findViewById(R.id.lv_list); mAdapter = new ArrayAdapter<String>(MainActivity.this, R.layout.item_log, R.id.item_log, new ArrayList<String>()); mResultListView.setAdapter(mAdapter); mSubscription.add(RetrofitService.getInstance().createService(GitHubApi.class) .getContributorsObservable("square", "retrofit").subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()).doOnSubscribe(new Action0() { @Override public void call() { mProgressBar.setVisibility(View.VISIBLE); } }).subscribe(new Observer<List<Contributor>>() { @Override public void onCompleted() { Logger.d("Retrofit call 1 completed"); mProgressBar.setVisibility(View.GONE); mResultListView.setVisibility(View.VISIBLE); ToastUtil.getInstance().showToast(MainActivity.this, "onCompleted"); } @Override public void onError(Throwable e) { mProgressBar.setVisibility(View.GONE); Logger.e(e.getMessage() + " woops we got an error while getting the list of contributors"); ToastUtil.getInstance().showToast(MainActivity.this, "onError"); } @Override public void onNext(List<Contributor> contributors) { ToastUtil.getInstance().showToast(MainActivity.this, "onNext"); for (Contributor c : contributors) { mAdapter.add(String.format("%s has made %d contributions to %s", c.login, c.contributions, "retrofit")); Logger.d(String.format("%s has made %d contributions to %s", c.login, c.contributions, "retrofit")); } } })); } private static final int COUNT = 10; private static final int TIME_ALL = 5000; private ArrayList<Long> timeList = new ArrayList<>(); private void method20() { final int COUNT = 5; final int TIME_ALL = 3000; final ArrayList<Long> timeList = new ArrayList<>(); final ArrayList<Long> allList = new ArrayList<>(); RxView.clicks(findViewById(R.id.iv_image)).map(new Func1<Void, Long>() { @Override public Long call(Void aVoid) { return System.currentTimeMillis(); } }).map(new Func1<Long, Boolean>() { @Override public Boolean call(Long nowTime) { allList.add(nowTime); timeList.add(nowTime); boolean isOver = false; Log.d(TAG, "timeList.size():" + timeList.size()); if (timeList.size() >= COUNT) { if (nowTime - timeList.get(0) < TIME_ALL) { isOver = true; } else { isOver = false; } timeList.clear(); } return isOver; } }).subscribe(new Action1<Boolean>() { @Override public void call(Boolean aBoolean) { if (aBoolean) { Toast.makeText(MainActivity.this, "3" + allList.size(), Toast.LENGTH_SHORT) .show(); allList.clear(); } else { // Toast.makeText(MainActivity.this, "ok "+timeList.size(), Toast.LENGTH_SHORT).show(); } } }); } public static String timeLongToString(long data) { Date date = new Date(data); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); return formatter.format(date); } private void log(final String str) { runOnUiThread(new Runnable() { @Override public void run() { Log.d(TAG, str); } }); } /** * ? * * @param number */ private void testFuncation(int number) { switch (number) { case 0: { method0(); break; } case 1: { method1(); break; } case 2: { method2(); break; } case 3: { method3(); break; } case 4: { method4(); break; } case 5: { method5(); break; } case 6: { method6(); break; } case 7: { method7(); break; } case 8: { method8(); break; } case 9: { method9(); break; } case 10: { method10(); break; } case 11: { method11(); break; } case 12: { method12(); break; } case 13: { method13(); break; } case 14: { method14(); break; } case 15: { method15(); break; } case 16: { method16(); break; } case 17: { method17(); break; } case 18: { method18(); break; } case 19: { method19(); break; } case 20: { method20(); break; } case 21: { method21(); break; } case 22: { method22(); break; } case 23: { method23(); break; } default: { break; } } } @Override public void onResume() { super.onResume(); mSubscription = RxUtils.getNewCompositeSubIfUnsubscribed(mSubscription); } @Override public void onPause() { super.onPause(); RxUtils.unsubscribeIfNotNull(mSubscription); } private boolean mGoToRecycleImageView = false; @Override protected void onDestroy() { super.onDestroy(); //rl_root_layout id unBingListener(findViewById(R.id.rl_root_layout)); unBindDrawables(findViewById(R.id.rl_root_layout)); recycleImageView(); } private void recycleImageView() { //ImageView?? if (mGoToRecycleImageView) { Logger.d("onDestroy()> RecycleBitmap.recycleImageView(mImageView)"); RecycleBitmap.recycleImageView(mImageView); mImageView.setImageBitmap(null); } if (mManyBitmapSuperposition != null && !mManyBitmapSuperposition.isRecycled()) { mManyBitmapSuperposition.recycle(); mManyBitmapSuperposition = null; } //@link http://blog.csdn.net/yanzi1225627/article/details/8236309 if (mCanvas != null) { //? Paint paint = new Paint(); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mCanvas.drawPaint(paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); mCanvas = null; } } /** * ???Activity onDestoryviewrootview * ?view?DrawingCache?? * Activity??????? * * @param view:the root view of the layout * @description Unbind the rootView * @author malin.myemail@gmail.com * @link http://stackoverflow.com/questions/9461364/exception-in-unbinddrawables * http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=400656149&idx=1&sn=122b4f4965fafebf78ec0b4fce2ef62a&3rd=MzA3MDU4NTYzMw==&scene=6#rd * @since 2015.12.16 */ private void unBindDrawables(View view) { if (view != null) { try { Drawable drawable = view.getBackground(); if (drawable != null) { drawable.setCallback(null); } else { } if (view instanceof ViewGroup && !(view instanceof AdapterView)) { ViewGroup viewGroup = (ViewGroup) view; int viewGroupChildCount = viewGroup.getChildCount(); for (int j = 0; j < viewGroupChildCount; j++) { unBindDrawables(viewGroup.getChildAt(j)); } viewGroup.removeAllViews(); } } catch (Exception e) { e.printStackTrace(); } } } /** * Remove an onclick listener * * @param view * @author malin.myemail@gmail.com * @website https://github.com/androidmalin * @data 2016/01/22 */ private void unBingListener(View view) { if (view != null) { try { if (view.hasOnClickListeners()) { view.setOnClickListener(null); } if (view instanceof ViewGroup && !(view instanceof AdapterView)) { ViewGroup viewGroup = (ViewGroup) view; int viewGroupChildCount = viewGroup.getChildCount(); for (int i = 0; i < viewGroupChildCount; i++) { unBingListener(viewGroup.getChildAt(i)); } } } catch (Exception e) { e.printStackTrace(); } } } //--------------------------------------- ----------------------------------------------------------- /** * :?assetsjpg,ImageView,,?--- ---- * ?RxJava-- -- */ //?:?6? //1:???assets?? //2:????assets?? //3:?JPG? //4:??bitmap //5:Bitmap //6:??UI,ImageView???Bitmap,??ProgressBar private void miZhiSuoJinAndNestedLoopAndCallbackHell() { new Thread(new Runnable() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { mProgressBar.setVisibility(View.VISIBLE); } }); //1:???assets?? ArrayList<String> assetsFolderNameList = ImageNameFactory.getAssetImageFolderName(); for (String folderName : assetsFolderNameList) { //2:????assets?? ArrayList<String> imagePathList = ImageUtils.getAssetsImageNamePathList(getApplicationContext(), folderName); for (final String imagePathName : imagePathList) { //3:?JPG? if (imagePathName.endsWith(JPG)) { //4:??bitmap final Bitmap bitmap = ImageUtils.getImageBitmapFromAssetsFolderThroughImagePathName( getApplicationContext(), imagePathName, Constant.IMAGE_WITH, Constant.IMAGE_HEIGHT); runOnUiThread(new Runnable() { @Override public void run() { //Logger.d(mCounter + ":" + imagePathName); //5:Bitmap createSingleImageFromMultipleImages(bitmap, mCounter); mCounter++; } }); } } } //6:??UI,ImageView???Bitmap,??ProgressBar runOnUiThread(new Runnable() { @Override public void run() { mImageView.setImageBitmap(mManyBitmapSuperposition); mProgressBar.setVisibility(View.GONE); } }); } }).start(); } /** * ,??:? * CanvasBitmap? * * @param bitmap:?Bitamp * @param mCounter:0 */ //?: //1:???Bitmap //2:BitmapBitmap,Bitmap?Canvas??. //3:???(64px*64px) //4:??Bitmap??,???,???,?? //5:Bitmap?? private void createSingleImageFromMultipleImages(Bitmap bitmap, int mCounter) { if (mCounter == 0) { //1:???Bitmap mManyBitmapSuperposition = Bitmap.createBitmap(DeviceInfo.screenWidthForPortrait, DeviceInfo.screenHeightForPortrait, bitmap.getConfig()); //2:BitmapBitmap mCanvas = new Canvas(mManyBitmapSuperposition); } if (mCanvas != null) { int left;//?? int top;//?? //3:???(64px*64px) int imageWidth = Constant.IMAGE_WITH; int imageHeight = Constant.IMAGE_HEIGHT; int number = DeviceInfo.screenHeightForPortrait / imageHeight;//??,? //4:??Bitmap??,???,???,?? if (mCounter >= (mCounter / number) * number && mCounter < (((mCounter / number) + 1) * number)) {//[0,number) left = (mCounter / number) * imageWidth; top = (mCounter % number) * imageHeight; // Log.d(TAG,""+mCounter+" left="+left+" top="+top); //5:Bitmap?? mCanvas.drawBitmap(bitmap, left, top, null); } } } /** * ? */ private void showMath() { String TAG = "Math"; for (int i = 0; i < 100; i++) { int ss = i / 10; int ww = i % 10; Log.d(TAG, i + "/10 ==" + ss); Log.d(TAG, i + "%10 ==" + ww); } } //-----------------------------------RxJava--?--??? ----------------------------------------------------------- private void rxJavaSolveMiZhiSuoJinAndNestedLoopAndCallbackHell() { //1:: //2:?? //3:?IO //4:? //5: //6:: mGoToRecycleImageView = false; Observable.from(ImageNameFactory.getAssetImageFolderName()) //assets??,assets .flatMap(new Func1<String, Observable<String>>() { @Override public Observable<String> call(String folderName) { return Observable .from(ImageUtils.getAssetsImageNamePathList(getApplicationContext(), folderName)); } }) //,jpg .filter(new Func1<String, Boolean>() { @Override public Boolean call(String imagePathNameAll) { return imagePathNameAll.endsWith(JPG); } }) //?Bitmap .map(new Func1<String, Bitmap>() { @Override public Bitmap call(String imagePathName) { return ImageUtils.getImageBitmapFromAssetsFolderThroughImagePathName( getApplicationContext(), imagePathName, Constant.IMAGE_WITH, Constant.IMAGE_HEIGHT); } }).map(new Func1<Bitmap, Void>() { @Override public Void call(Bitmap bitmap) { createSingleImageFromMultipleImages(bitmap, mCounter); mCounter++; return null; } }).subscribeOn(Schedulers.io())//?IO .doOnSubscribe(new Action0() { @Override public void call() { mProgressBar.setVisibility(View.VISIBLE); } }).observeOn(AndroidSchedulers.mainThread())//? .subscribe(new Subscriber<Void>() { @Override public void onCompleted() { mImageView.setImageBitmap(mManyBitmapSuperposition); mProgressBar.setVisibility(View.GONE); } @Override public void onError(Throwable e) { //Toast.makeText(MainActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override public void onNext(Void aVoid) { } }); } }