├── .gitignore ├── .gradle ├── 2.10 │ └── taskArtifacts │ │ ├── cache.properties │ │ ├── cache.properties.lock │ │ ├── fileHashes.bin │ │ ├── fileSnapshots.bin │ │ ├── outputFileStates.bin │ │ └── taskArtifacts.bin └── 2.8 │ └── taskArtifacts │ ├── cache.properties │ ├── cache.properties.lock │ ├── fileHashes.bin │ ├── fileSnapshots.bin │ ├── outputFileStates.bin │ └── taskArtifacts.bin ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── libraries │ ├── hamcrest_core_1_3.xml │ └── junit_4_12.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml ├── vcs.xml └── workspace.xml ├── Blogs ├── Algorithms │ ├── Day2Sort.java │ ├── InsertionSort.java │ ├── SelectionSort.java │ ├── Sorts.java │ ├──  熟悉常用数据结构和算法Android原生框架的了解熟悉OOP熟悉常用的设计模式熟悉Android系统架构、UI框架及相关技术.md │ └── 排序总结.md ├── Android-Classical-OpenSource │ └── Android-Classical-OpenSource.md ├── AndroidMvp │ └── AndroidMvp │ │ ├── .gitignore │ │ ├── .idea │ │ ├── .name │ │ ├── compiler.xml │ │ ├── copyright │ │ │ └── profiles_settings.xml │ │ ├── encodings.xml │ │ ├── gradle.xml │ │ ├── misc.xml │ │ ├── modules.xml │ │ ├── runConfigurations.xml │ │ └── vcs.xml │ │ ├── app │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── eterrao │ │ │ │ └── androidmvp │ │ │ │ └── ApplicationTest.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── io │ │ │ │ │ └── github │ │ │ │ │ └── eterrao │ │ │ │ │ └── androidmvp │ │ │ │ │ ├── activity │ │ │ │ │ ├── BaseActivity.java │ │ │ │ │ └── LoginActivity.java │ │ │ │ │ ├── iview │ │ │ │ │ ├── IView.java │ │ │ │ │ └── LoginView.java │ │ │ │ │ ├── listener │ │ │ │ │ └── OnLoginStatusListener.java │ │ │ │ │ ├── model │ │ │ │ │ ├── ILoginModel.java │ │ │ │ │ ├── LoginModel.java │ │ │ │ │ └── RequestCallbackable.java │ │ │ │ │ ├── presenter │ │ │ │ │ ├── BasePresenter.java │ │ │ │ │ └── Presenter.java │ │ │ │ │ └── utils │ │ │ │ │ └── HttpUtils.java │ │ │ └── res │ │ │ │ ├── layout │ │ │ │ └── activity_login.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ └── values │ │ │ │ ├── colors.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── eterrao │ │ │ └── androidmvp │ │ │ └── ExampleUnitTest.java │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle ├── DesignPattern │ ├── MVP │ │ └── MVP for Android.md │ └── SingletonInstance │ │ ├── SingletonOfDCL.java │ │ ├── SingletonOfEager.java │ │ ├── SingletonOfInnerClass.java │ │ └── SingletonOfLazy.java ├── DifferenceOfYUV │ ├── DifferenceOfYUV.md │ ├── YUVFrame │ │ ├── .gitignore │ │ ├── .idea │ │ │ ├── .name │ │ │ ├── compiler.xml │ │ │ ├── copyright │ │ │ │ └── profiles_settings.xml │ │ │ ├── encodings.xml │ │ │ ├── gradle.xml │ │ │ ├── misc.xml │ │ │ ├── modules.xml │ │ │ ├── runConfigurations.xml │ │ │ └── vcs.xml │ │ ├── app │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── androidTest │ │ │ │ └── java │ │ │ │ │ └── io │ │ │ │ │ └── github │ │ │ │ │ └── eterrao │ │ │ │ │ └── yuvframe │ │ │ │ │ └── ApplicationTest.java │ │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ │ └── io │ │ │ │ │ │ └── github │ │ │ │ │ │ └── eterrao │ │ │ │ │ │ └── yuvframe │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res │ │ │ │ │ ├── layout │ │ │ │ │ └── activity_main.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── values-w820dp │ │ │ │ │ └── dimens.xml │ │ │ │ │ └── values │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── eterrao │ │ │ │ └── yuvframe │ │ │ │ └── ExampleUnitTest.java │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── fig1.gif │ └── fig2.gif ├── Java │ └── Java基础.md ├── OpenApi │ └── 开放API汇总.md ├── Other │ └── 【Android】[转] Android Codec默认profile使用的是Baseline.md ├── ThinkingInJava │ └── final的几个注意点.md ├── interview │ └── AndroidInterview-Q-A.md └── leetCode │ ├── AddDigits.java │ ├── ReverseInteger.java │ ├── ReverseString.java │ ├── ReverseStringVowels.java │ ├── ReverseStringVowelsStringArray.java │ ├── SumofTwoIntegers.java │ ├── TwoSums.java │ └── untitled ├── GDGTicket.jpg ├── LeetCode刷题页.png ├── LeetCode官网.png ├── LeetCode算法入口.png ├── LeetCode题目概览.png ├── MySplashGif.gif ├── ScaleGif.gif ├── YouzanSplashGif.gif ├── androidPainterDemo.png ├── animatorWithXML.png ├── electron-dict-demo.gif ├── objectAnimatorAttrs.png ├── personalWorkSummary.jpg └── 海贼王OP.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ### Java template 3 | *.class 4 | 5 | # Mobile Tools for Java (J2ME) 6 | .mtj.tmp/ 7 | 8 | # Package Files # 9 | *.jar 10 | *.war 11 | *.ear 12 | 13 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 14 | hs_err_pid* 15 | 16 | # Created by .ignore support plugin (hsz.mobi) 17 | ======= 18 | # Built application files 19 | *.apk 20 | *.ap_ 21 | 22 | # Files for the Dalvik VM 23 | *.dex 24 | 25 | # Java class files 26 | *.class 27 | 28 | # Generated files 29 | bin/ 30 | gen/ 31 | 32 | # Gradle files 33 | .gradle/ 34 | build/ 35 | /*/build/ 36 | 37 | # Local configuration file (sdk path, etc) 38 | local.properties 39 | 40 | # Proguard folder generated by Eclipse 41 | proguard/ 42 | 43 | # Log Files 44 | *.log 45 | >>>>>>> e0d2e22cbfc43852e98da0c7a03033e9a20d8fc0 46 | -------------------------------------------------------------------------------- /.gradle/2.10/taskArtifacts/cache.properties: -------------------------------------------------------------------------------- 1 | #Sun May 01 21:31:13 CST 2016 2 | -------------------------------------------------------------------------------- /.gradle/2.10/taskArtifacts/cache.properties.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.10/taskArtifacts/cache.properties.lock -------------------------------------------------------------------------------- /.gradle/2.10/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.10/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/2.10/taskArtifacts/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.10/taskArtifacts/fileSnapshots.bin -------------------------------------------------------------------------------- /.gradle/2.10/taskArtifacts/outputFileStates.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.10/taskArtifacts/outputFileStates.bin -------------------------------------------------------------------------------- /.gradle/2.10/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.10/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /.gradle/2.8/taskArtifacts/cache.properties: -------------------------------------------------------------------------------- 1 | #Sun Apr 24 23:17:47 CST 2016 2 | -------------------------------------------------------------------------------- /.gradle/2.8/taskArtifacts/cache.properties.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.8/taskArtifacts/cache.properties.lock -------------------------------------------------------------------------------- /.gradle/2.8/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.8/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/2.8/taskArtifacts/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.8/taskArtifacts/fileSnapshots.bin -------------------------------------------------------------------------------- /.gradle/2.8/taskArtifacts/outputFileStates.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.8/taskArtifacts/outputFileStates.bin -------------------------------------------------------------------------------- /.gradle/2.8/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myrao/BlogExamples/fd1c50a707f892e76644e2ff4a7302e270cd0cbe/.gradle/2.8/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | CameraFrameDemo -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/libraries/hamcrest_core_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/junit_4_12.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Android Lint 19 | 20 | 21 | Gradle 22 | 23 | 24 | Probable bugsGradle 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.7 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Blogs/Algorithms/Day2Sort.java: -------------------------------------------------------------------------------- 1 | public class Day2Sort { 2 | 3 | /** 4 | *快速排序 5 | */ 6 | public static void quickSort(int[] list) { 7 | quickSort(list, 0, list.length - 1); 8 | } 9 | 10 | public static void quickSort(int[] list, int first, int last) { 11 | if (last > first) { 12 | int pivotIndex = partition(list, first, last); 13 | quickSort(list, first, pivotIndex - 1);; 14 | quickSort(list, pivotIndex + 1, last);\ 15 | } 16 | } 17 | 18 | public static int partition(int[] list, int first, int last){ 19 | int pivot = list[first]; 20 | int low = first + 1; 21 | int high = last; 22 | while (high > low) { 23 | while (low <= high && list[low] < pivot) { 24 | low++; 25 | } 26 | 27 | while (low <= high && list[high] > pivot) { 28 | high--; 29 | } 30 | 31 | if (high > low) { 32 | int temp = list[high]; 33 | list[high] = list[low]; 34 | list[low] = temp; 35 | } 36 | } 37 | 38 | while (high > first && list[high] > pivot) { 39 | high--; 40 | } 41 | 42 | if (pivot < list[high]) { 43 | list[first] = list[high]; 44 | list[high] = pivot; 45 | return high; 46 | } else { 47 | return first; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Blogs/Algorithms/InsertionSort.java: -------------------------------------------------------------------------------- 1 | public class InsertionSort { 2 | public static void sort(Comparabale[] array) { 3 | int N = array.length(); 4 | for (int i = 0; i < N ; i++) { 5 | for (int j = N; j > 0 && less(array[j], array[j - 1]); j-- ) { 6 | exchange(array, j, j - 1); 7 | } 8 | } 9 | } 10 | 11 | public static boolean less(int a, int b) { 12 | return (a - b < 0) ? true : false; 13 | } 14 | 15 | public static void exchange(Comparabale[] array, int i, j){ 16 | int temp = array[i]; 17 | array[i] = array[j]; 18 | array[j] = temp; 19 | } 20 | } -------------------------------------------------------------------------------- /Blogs/Algorithms/SelectionSort.java: -------------------------------------------------------------------------------- 1 | public class SelectionSort { 2 | public static void sort(Comparable[] array) { 3 | int N = array.length(); 4 | for (int i = 0; i < N; i++) { 5 | int min = i; 6 | for (int j = i + 1; j < N; j++) { 7 | if (array[j] < array[min]) { 8 | min = j; 9 | } 10 | } 11 | // 把选择出来的当前最小的元素放到最左边 12 | if (min != i) { 13 | int temp = array[i]; 14 | array[i] = array[min]; 15 | array[min] = temp; 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Blogs/Algorithms/Sorts.java: -------------------------------------------------------------------------------- 1 | public class Sorts { 2 | 3 | /** 4 | * 冒泡排序 5 | */ 6 | public static void BubbleSortFakeCode(int[] list) { 7 | if (list.length == 0) { 8 | return; 9 | } 10 | boolean needNextPass = true; 11 | for (int k = 1; k < list.length && needNextPass; k++) { 12 | needNextPass = false; 13 | for (int i; i < list.length - k; i++) { 14 | if (list[i] > list[i + 1]) { 15 | swap list[i] with list[i + 1]; 16 | int temp = list[i]; 17 | list[i] = list[i + 1]; 18 | list[i + 1] = list[i]; 19 | needNextPass = true; 20 | } 21 | } 22 | } 23 | } 24 | 25 | /** 26 | * 归并排序 27 | * 使用到了System.arraycopy这个方法 28 | * public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 29 | */ 30 | public static void mergeSort(int[] list) { 31 | // if (list.length > 1) { 32 | // mergeSort(list[0... list.length / 2]); 33 | // mergeSort(list[list.length / 2 + 1 ... list.length]); 34 | // merge list[0... list.length / 2] with list[list.length / 2 + 1 ... list.length]; 35 | // } 36 | 37 | if (list.length > 1) { 38 | int[] firstHalf = new int[list.length / 2]; 39 | System.arraycopy(list, 0, firstHalf, 0, list.length / 2); 40 | mergeSort(firstHalf); 41 | 42 | int secondHalfLength = list.length - list.length / 2; 43 | int[] secondHalf = new int[secondHalfLength]; 44 | System.arraycopy(list, list.length / 2, secondHalf, 0, secondHalfLength); 45 | mergeSort(secondHalf); 46 | 47 | merge(firstHalf, secondHalf, list); 48 | } 49 | } 50 | 51 | public static void merge(int[] list1, int[] list2, int[] temp) { 52 | int current1 = 0; // current index in list1 53 | int current2 = 0; // current index in list2 54 | int current3 = 0; // current index in temp 55 | 56 | while (current1 < list1.length && current2 < list2.length) { 57 | if (list1[current1] < list2[current2]) { 58 | temp[current3++] = list1[current1++]; 59 | } else { 60 | temp[current3++] = list2[current2++]; 61 | } 62 | 63 | } 64 | 65 | while (current1 < list1.length) { 66 | temp[current3++] = list1[current1++]; 67 | } 68 | 69 | while (current2 < list2.length) { 70 | temp[current3++] = list2[current2++]; 71 | } 72 | } 73 | 74 | 75 | 76 | /** 77 | * 快速排序 78 | * 首先快排先将一个数组通过一个pivot将其划分为二 79 | * 然后递归的对其左序列和右序列进行排序,因此quickSort方法应该有三 80 | * 注意快排和归并的时间复杂度为O(nlogn) 81 | */ 82 | public static void quickSort(int[] list) { 83 | quickSort(list, 0, list.length - 1); 84 | } 85 | 86 | public static void quickSort(int[] list, int first, int last) { 87 | if (last > first) { 88 | int pivotIndex = partition(list, first, last); 89 | quickSort(list, first, pivotIndex - 1); 90 | quickSort(list, pivotIndex + 1, last); 91 | } 92 | } 93 | 94 | public static int partition(int[] list, int first, int last) { 95 | int pivot = list[first]; // choose the first element as the pivot 96 | int low = first + 1; // Index for forward search 97 | int high = last; // Index for backward search 98 | 99 | while (high > low) { 100 | // Search forward from left 101 | while (low <= high && list[low] < pivot) { 102 | low++; 103 | } 104 | 105 | while (low <= high && list[high] >= pivot) { 106 | high--; 107 | } 108 | 109 | if (high > low) { 110 | int temp = list[low]; 111 | list[low] = list[high]; 112 | list[high] = temp; 113 | } 114 | } 115 | 116 | while (high > first && list[high] >= pivot) { 117 | high--; 118 | } 119 | 120 | if (pivot < list[high]) { 121 | list[first] = list[high]; 122 | list[high] = pivot; 123 | return high; 124 | } else { 125 | return first; 126 | } 127 | 128 | } 129 | } -------------------------------------------------------------------------------- /Blogs/Algorithms/ 熟悉常用数据结构和算法Android原生框架的了解熟悉OOP熟悉常用的设计模式熟悉Android系统架构、UI框架及相关技术.md: -------------------------------------------------------------------------------- 1 | # 面试准备 2 | 3 | ### 2016年7月7日建 4 | 5 | ##### 说明: 6 | 7 | 计划该月准备面试相关的知识点和简历的书写及投递,简历每天完成一些,初稿请师父帮忙审阅,终稿投递乐视,目标乐视汽车研发组 8 | 9 | ##### 时长: 10 | 11 | 约20~30天 12 | 13 | ##### 准备内容: 14 | 15 | 16 | -  熟悉常用数据结构和算法 17 | -  看书刷题 18 | 19 | 20 | -  Android原生框架的了解 21 | -  阅读源码 22 | 23 | 24 | -  熟悉OOP及常用的设计模式 25 | -  阅读设计模式相关书籍,思考,写代码 26 | 27 | 28 | -  熟悉Android系统架构、UI框架及相关技术 29 | 30 | 31 | 32 | ## 数据结构与算法 33 | 34 | ##### 基本排序 35 | 36 | - 插入排序 37 | - 归并排序 38 | - 堆排序 39 | - 快速排序 40 | - 基数排序 41 | - 计数排序 42 | - 冒泡排序 43 | - 桶排序 44 | - 希尔排序 45 | 46 | ##### 数据结构 47 | 48 | - 栈和队列 49 | - 链表 50 | - 二叉搜索树 51 | - *红黑树 52 | - 散列表 53 | 54 | ##### 算法设计技巧 55 | 56 | - 贪婪算法 57 | - 分治算法 58 | 59 | ## LeetCode刷题 60 | 61 | - 300道题左右 -------------------------------------------------------------------------------- /Blogs/Algorithms/排序总结.md: -------------------------------------------------------------------------------- 1 | ### 排序总结 2 | 3 | #### 插入排序 4 | 5 | - 时间复杂度:O(n) 6 | - ​ -------------------------------------------------------------------------------- /Blogs/Android-Classical-OpenSource/Android-Classical-OpenSource.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Android-Classical-OpenSource 3 | tags: Android 4 | keywords: Android, Github 5 | categories: Android 6 | --- 7 | 8 | # Android-Classical-OpenSource 9 | 10 | Android开发中 个人遇到和使用过的值得分享的资源合集 11 | 12 | # [Trinea的OpenProject](https://github.com/Trinea/android-open-project) 13 | 强烈推荐的Android 开源项目分类汇总,star数量1.7W+ 14 | #### 项目说明: 15 | 16 | > Android 开源项目第一篇——个性化控件(View)篇 17 | > 包括ListView、ActionBar、Menu、ViewPager、Gallery、GridView、ImageView、ProgressBar、TextView、ScrollView、TimeView、TipView、FlipView、ColorPickView、GraphView、UI Style、其他 18 | > Android 开源项目第二篇——工具库篇 19 | > 包括依赖注入、图片缓存、网络请求、数据库 ORM 工具包、Android 公共库、高版本向低版本兼容库、多媒体、事件总线、传感器、安全、插件化、文件、其他 20 | > Android 开源项目第三篇——优秀项目篇 21 | > 比较有意思的完整的 Android 项目 22 | > Android 开源项目第四篇——开发及测试工具篇 23 | > 包括开发效率工具、开发自测相关、测试工具、开发及编译环境、其他 24 | > Android 开源项目第五篇——优秀个人和团体篇 25 | > 乐于分享并且有一些很不错的开源项目的个人和组织,包括 JakeWharton、Chris Banes、Koushik Dutta 等 26 | 27 | ------ 28 | 29 | # [awesome-android-ui](https://github.com/wasabeef/awesome-android-ui) 30 | 31 | #### 项目说明: 32 | 33 | 国外wasabeef大神分享的一个库,同上面Trinea开源的共享库。 34 | 35 | > A curated list of awesome Android UI/UX libraries. 36 | 37 | --- 38 | 39 | # [AndroidDevTools 开源项目分类汇总](https://github.com/inferjay/AndroidDevTools) 40 | 41 | #### [官方网站](http://www.androiddevtools.cn/ ) 42 | 43 | #### 项目说明: 44 | 45 | > 收集整理Android开发所需的Android SDK、开发中用到的工具、Android开发教程、Android设计规范,免费的设计素材等。 46 | > 欢迎大家推荐自己在Android开发过程中用的好用的工具、学习开发教程、用到设计素材,欢迎Star、Fork 😄。 47 | 48 | ------ 49 | 50 | # [android-tech-frontier](https://github.com/eterrao/android-tech-frontier.git) 51 | 52 | #### 项目说明: 53 | 54 | > 一个定期翻译、发布国内外Android优质的技术、开源库、软件架构设计、测试等文章的开源项目,让我们的技术跟上国际步伐。 55 | > 56 | > 我们翻译的文章在能够联系到作者的情况下都会在获得作者授权后进行翻译,并且公开发布。发布的文章中都会保留原文链接、作者名,如有相关的版权协议我们也会一并附上。目前已经联系到的作者列表请参考授权文档; 57 | 58 | 59 | 60 | ------ 61 | 62 | # [List of Free Learning Resources](https://github.com/vhf/free-programming-books) 63 | 64 | 超神的资源网站,各种国家的编程资料、电子书和博客,应有尽有。 65 | 66 | ------ 67 | 68 | #个人博客资源: 69 | 70 | 71 | ## [stormZhang](http://stormzhang.com/) 72 | 73 | 每个人都有一段艰辛、苦逼的成长时光,所以学会从博客开始记录自己一点一滴。这个博客的文章每次看都让自己有更多的动力去学习。提醒自己别忘了还有梦想。 74 | PS:`还有很多干货`。 75 | 76 | ------ 77 | 78 | 79 | ##[tickTick 的BLOG](http://ticktick.blog.51cto.com) 80 | 81 | > 本目录下的代码都是来自于我的博客《Android应用开发》系列文章,本系列文章介绍Android开发的一些基础和进阶知识,并附带有一些简单的Demo示例,这些示例代码中很多Java文件都对Android API进行了良好的封装,可以直接拿到自己的项目中使用。 82 | > 83 | > **Code List** 84 | > Builder 给出了使用ant编译Android工程的通用shell脚本,相关博文:Android开发实践:用脚本编译Android工程 85 | > 86 | > **GroupList** 87 | > 封装并演示了如何使用Android的ExpandableListView控件,相关博文:Android开发实践:多级列表的封装与应用 88 | > 89 | > **PopDialog** 90 | > 封装并演示了如何使用Android的PopupWindow控件,相关博文:Android开发实践:用PopupWindow实现自定义Dailog 91 | > 92 | > **JniCallback** 93 | > 演示了如何从Native线程回调Java的函数,相关博文:Android开发实践:JNI层线程回调Java函数示例 94 | > 95 | > **JniBuffer** 96 | > 演示了各种从Java端到Native层的Buffer传递方法,相关博文:Android开发实践:Java层与Jni层的数组传递 97 | > 98 | > **LoopThread** 99 | > 演示了如何实现一个自定义的带Loop消息循环的线程,相关博文:Android开发实践:自定义带消息循环(Looper)的工作线程 100 | > 101 | > **VideoPlayer** 102 | > 演示了Android隐式Intent的用法,相关博文:Android开发实践:实战演练隐式Intent的用法 103 | > 104 | > **VideoServer** 105 | > 演示了如何利用NanoHttpd搭建一个Android视频服务器,相关博文:基于NanoHttpd的Android视频服务器开发 106 | > 107 | > **CustomView** 108 | > 演示了如何自定义View和ViewGroup,并给出了一个柱状图动画自定义View的实现,相关博文: 109 | > 110 | > (1)Android开发实践:为什么要继承onMeasure() 111 | > 112 | > (2)Android开发实践:自定义ViewGroup的onLayout()分析 113 | > 114 | > (3)Android开发实践:自定义带动画的View 115 | > 116 | > **WIFI** 封装了Andriod WIFI扫描和连接的相关API,相关博文: 117 | > 118 | > (1)Android开发实践:WIFI扫描功能的封装 119 | > 120 | > (2)Android开发实践:WIFI连接功能的封装 121 | > 122 | > **Socket**封装了Android中的Socket相关API 123 | > 124 | > (1) Broadcaster.java 封装了UDP广播包的收发操作,相关博文:Android Socket 发送广播包的那些坑 125 | > 126 | > MediaDemo 给出了Android平台下多媒体相关API的demo代码,相关博文:Android中如何提取和生成mp4文件 127 | > 128 | > **Utils** 给出了一系列的工具类代码 129 | > 130 | > (1)SignatureGen.java 一个可以生成Java函数签名字符串的工具类,相关博文: Android开发实践:JNI函数签名生成器 131 | > 132 | > (2)BitmapHelper.java 一个封装了Bitmap操作的工具类,包括图片的打开、保存、剪裁、旋转等操作,相关博文: Android开发实践:自己动手编写图片剪裁应用(3) 133 | > 134 | > (3)ImageConvertor.java 封装了Android中各种图像格式转换,包括:NV21,YUY2、RGB565、ARGB8888、PNG、JPEG、Bitmap之间的转换操作。 135 | > 136 | 137 | ------ 138 | 139 | # 工具类: 140 | 141 | ## 通用 142 | 143 | - 关于APK瘦身值得分享的一些经验: 144 | - PNG压缩: 145 | 146 | 147 | ------ 148 | 149 | ## MarkDown编辑器 150 | 151 | ### [Typora](http://www.typora.io/) 152 | 正在使用,简单方便。**强烈推荐!** 153 | 154 | - 优点: 155 | - 实时预览 156 | - 支持常用的几种主题(GitHub、Night等等) 157 | - 快捷键插入十分方便 158 | - 支持代码的高亮及多种语言的高亮选择 159 | 160 | **注意**: 由于是国外网站,所以下载比较慢,耐心等待 161 | 162 | ### [Mou](http://25.io/mou/) 163 | 164 | 该有的都有了,羞耻的使用了破解版,但是个人唯一受不了的是这货居然不支持多窗口!! 165 | 166 | - 优点:左边编辑右边实时预览; 167 | - 缺点: 168 | - 不支持多窗口,不知道能不能设置; 169 | - 收费软件; 170 | 171 | ### [Cmd Markdown编辑器](https://www.zybuluo.com/mdeditor#403095) 172 | 173 | 一款**在线**编辑的MarkDown编辑器,设计简洁。 174 | 175 | - 优点: 176 | - 浏览器在线编辑,可以实时同步到不同的设备 177 | - 支持导出的格式挺多 178 | - 缺点: 179 | - 需要注册登录账号 180 | - 没有网貌似没法用 181 | 182 | ### [StackEdit](https://stackedit.io/editor) 183 | 184 | 同样是**在线**编辑器,国外的 185 | 186 | --- 187 | 188 | 189 | ## 真机调试 190 | 191 | - **[云测 (Testin)](http://www.testin.cn/)** 192 | 193 | - **[优测 (腾讯的)](http://utest.qq.com/)** 194 | 195 | 196 | ## 数据统计 / Bug / Crash Reporter 197 | 198 | ### **国内** 199 | 200 | #### **[友盟](http://www.umeng.com/)** 201 | 202 | 友盟的功能集成挺多,常用的基本都覆盖了,社会化组件/数据统计/Bug分析基本都通用,并且使用起来比较直观。SDK使用的话也不算麻烦。 203 | 优点就不说了,说说缺点吧,就是Crash Report不能实时邮件反馈,第二天9点30左右才会收到前一天的统计概况。详情的话倒是可以实时查询。 204 | 205 | ### 国外 206 | 207 | #### **[Fabric]( https://fabric.io/) (Twitter出的)** 208 | 209 | - **优点**:反馈及时,一般有了Bug邮件没过多久就收到了,并且集成起来很方便,基于Android Studio的一个插件自动将SDK打入项目中。 210 | - **缺点**:如果平时Debug频率高的话建议关闭,每次切换分之如果有什么意外总会重新拉取最新的版本,一等就是十几分钟,等待真正公测的时候再打开,这样信息比较准确,还有建议测试的时候打包使用Debug版本号,能够在日志清楚的区分线上线下版本。 211 | 212 | ------ 213 | 214 | ## 公共API 215 | 216 | ### [和风天气](http://www.heweather.com/) 217 | 218 | 一款功能较多,可以免费使用的天气API(免费的日访问量为3000,开发练手足够了)。 219 | 220 | ### [干货集中营](http://gank.io/api) 221 | 222 | 想要更多API?来这里吧,各种福利、干活日日推荐。 223 | 224 | ### [Unsplash](https://unsplash.it/) 225 | 226 | 一个全球集中的图片开放API 227 | 228 | ------ 229 | 230 | # 面试相关 231 | 232 | 面试,面试,面试!重要的事情说三遍! 233 | 234 | ## [AndroidInterview-Q-A](https://github.com/JackyAndroid/AndroidInterview-Q-A) 235 | 236 | > 以下面试题来自于百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐内部题库 237 | > 238 | > 熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。 239 | > 240 | > ### 一、Java基础 241 | > 242 | > ### 二、Android基础 243 | 244 | ------ 245 | 246 | ## [LearningNotes](https://github.com/GeniusVJR/LearningNotes) 247 | 248 | 内容涵盖了Android各大知识点,不必要都看别人总结的,可以自己试着总结这样学习更快,但可以根据别人列出的知识点查缺补漏。博主第六部分的**面试经验**值得借鉴 249 | 250 | ------ 251 | 252 | ## [一个五年Android开发者百度、阿里、聚美、映客的面试心经](http://gdky005.com/) 253 | 254 | > 先简单说说我最近的面试经历吧。面试的公司很多,其中有让我心血沸腾的经历,也有让我感到失望到无助的经历,我将这些体会都记录下来,细想之后很值得,面了这么多公司,要是最后什么也没有留下来,那就太浪费了。至少对于我来说有些东西在整理总结之后才能得到一个肯定的答案。希望这些能对即将换工作或者打算看看机会的你有一些帮助。 255 | > 256 | > …... 257 | 258 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/.name: -------------------------------------------------------------------------------- 1 | AndroidMvp -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 26 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Android Lint 46 | 47 | 48 | Gradle 49 | 50 | 51 | Probable bugsGradle 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 73 | 74 | 75 | 76 | 77 | Android API 21 Platform 78 | 79 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "io.github.eterrao.androidmvp" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.4.0' 26 | compile 'com.android.support:design:23.4.0' 27 | } 28 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Applications/adt-bundle-mac-x86_64/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/androidTest/java/io/github/eterrao/androidmvp/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/activity/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.activity; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | import io.github.eterrao.androidmvp.presenter.BasePresenter; 7 | 8 | /** 9 | * Created by raomengyang on 6/25/16. 10 | */ 11 | public abstract class BaseActivity

extends Activity { 12 | 13 | private P presenter; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | presenter = initPresenter(); 18 | super.onCreate(savedInstanceState); 19 | initViews(); 20 | } 21 | 22 | protected abstract P initPresenter(); 23 | 24 | protected abstract void initViews(); 25 | 26 | 27 | @Override 28 | protected void onDestroy() { 29 | super.onDestroy(); 30 | if (presenter != null) presenter.detachView(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/activity/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.activity; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorListenerAdapter; 5 | import android.annotation.TargetApi; 6 | import android.content.pm.PackageManager; 7 | import android.support.annotation.NonNull; 8 | import android.support.design.widget.Snackbar; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.app.LoaderManager.LoaderCallbacks; 11 | 12 | import android.content.CursorLoader; 13 | import android.content.Loader; 14 | import android.database.Cursor; 15 | import android.net.Uri; 16 | import android.os.AsyncTask; 17 | 18 | import android.os.Build; 19 | import android.os.Bundle; 20 | import android.provider.ContactsContract; 21 | import android.text.TextUtils; 22 | import android.view.KeyEvent; 23 | import android.view.View; 24 | import android.view.View.OnClickListener; 25 | import android.view.inputmethod.EditorInfo; 26 | import android.widget.ArrayAdapter; 27 | import android.widget.AutoCompleteTextView; 28 | import android.widget.Button; 29 | import android.widget.EditText; 30 | import android.widget.TextView; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | import io.github.eterrao.androidmvp.R; 36 | 37 | import static android.Manifest.permission.READ_CONTACTS; 38 | 39 | /** 40 | * A login screen that offers login via email/password. 41 | */ 42 | public class LoginActivity extends AppCompatActivity implements LoaderCallbacks { 43 | 44 | /** 45 | * Id to identity READ_CONTACTS permission request. 46 | */ 47 | private static final int REQUEST_READ_CONTACTS = 0; 48 | 49 | /** 50 | * A dummy authentication store containing known user names and passwords. 51 | * TODO: remove after connecting to a real authentication system. 52 | */ 53 | private static final String[] DUMMY_CREDENTIALS = new String[]{ 54 | "foo@example.com:hello", "bar@example.com:world" 55 | }; 56 | /** 57 | * Keep track of the login task to ensure we can cancel it if requested. 58 | */ 59 | private UserLoginTask mAuthTask = null; 60 | 61 | // UI references. 62 | private AutoCompleteTextView mEmailView; 63 | private EditText mPasswordView; 64 | private View mProgressView; 65 | private View mLoginFormView; 66 | 67 | @Override 68 | protected void onCreate(Bundle savedInstanceState) { 69 | super.onCreate(savedInstanceState); 70 | setContentView(R.layout.activity_login); 71 | // Set up the login form. 72 | mEmailView = (AutoCompleteTextView) findViewById(R.id.email); 73 | populateAutoComplete(); 74 | 75 | mPasswordView = (EditText) findViewById(R.id.password); 76 | mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() { 77 | @Override 78 | public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { 79 | if (id == R.id.login || id == EditorInfo.IME_NULL) { 80 | attemptLogin(); 81 | return true; 82 | } 83 | return false; 84 | } 85 | }); 86 | 87 | Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button); 88 | mEmailSignInButton.setOnClickListener(new OnClickListener() { 89 | @Override 90 | public void onClick(View view) { 91 | attemptLogin(); 92 | } 93 | }); 94 | 95 | mLoginFormView = findViewById(R.id.login_form); 96 | mProgressView = findViewById(R.id.login_progress); 97 | } 98 | 99 | private void populateAutoComplete() { 100 | if (!mayRequestContacts()) { 101 | return; 102 | } 103 | 104 | getLoaderManager().initLoader(0, null, this); 105 | } 106 | 107 | private boolean mayRequestContacts() { 108 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 109 | return true; 110 | } 111 | if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) { 112 | return true; 113 | } 114 | if (shouldShowRequestPermissionRationale(READ_CONTACTS)) { 115 | Snackbar.make(mEmailView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE) 116 | .setAction(android.R.string.ok, new View.OnClickListener() { 117 | @Override 118 | @TargetApi(Build.VERSION_CODES.M) 119 | public void onClick(View v) { 120 | requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS); 121 | } 122 | }); 123 | } else { 124 | requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS); 125 | } 126 | return false; 127 | } 128 | 129 | /** 130 | * Callback received when a permissions request has been completed. 131 | */ 132 | @Override 133 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 134 | @NonNull int[] grantResults) { 135 | if (requestCode == REQUEST_READ_CONTACTS) { 136 | if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 137 | populateAutoComplete(); 138 | } 139 | } 140 | } 141 | 142 | 143 | /** 144 | * Attempts to sign in or register the account specified by the login form. 145 | * If there are form errors (invalid email, missing fields, etc.), the 146 | * errors are presented and no actual login attempt is made. 147 | */ 148 | private void attemptLogin() { 149 | if (mAuthTask != null) { 150 | return; 151 | } 152 | 153 | // Reset errors. 154 | mEmailView.setError(null); 155 | mPasswordView.setError(null); 156 | 157 | // Store values at the time of the login attempt. 158 | String email = mEmailView.getText().toString(); 159 | String password = mPasswordView.getText().toString(); 160 | 161 | boolean cancel = false; 162 | View focusView = null; 163 | 164 | // Check for a valid password, if the user entered one. 165 | if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) { 166 | mPasswordView.setError(getString(R.string.error_invalid_password)); 167 | focusView = mPasswordView; 168 | cancel = true; 169 | } 170 | 171 | // Check for a valid email address. 172 | if (TextUtils.isEmpty(email)) { 173 | mEmailView.setError(getString(R.string.error_field_required)); 174 | focusView = mEmailView; 175 | cancel = true; 176 | } else if (!isEmailValid(email)) { 177 | mEmailView.setError(getString(R.string.error_invalid_email)); 178 | focusView = mEmailView; 179 | cancel = true; 180 | } 181 | 182 | if (cancel) { 183 | // There was an error; don't attempt login and focus the first 184 | // form field with an error. 185 | focusView.requestFocus(); 186 | } else { 187 | // Show a progress spinner, and kick off a background task to 188 | // perform the user login attempt. 189 | showProgress(true); 190 | mAuthTask = new UserLoginTask(email, password); 191 | mAuthTask.execute((Void) null); 192 | } 193 | } 194 | 195 | private boolean isEmailValid(String email) { 196 | //TODO: Replace this with your own logic 197 | return email.contains("@"); 198 | } 199 | 200 | private boolean isPasswordValid(String password) { 201 | //TODO: Replace this with your own logic 202 | return password.length() > 4; 203 | } 204 | 205 | /** 206 | * Shows the progress UI and hides the login form. 207 | */ 208 | @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) 209 | private void showProgress(final boolean show) { 210 | // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow 211 | // for very easy animations. If available, use these APIs to fade-in 212 | // the progress spinner. 213 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 214 | int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); 215 | 216 | mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 217 | mLoginFormView.animate().setDuration(shortAnimTime).alpha( 218 | show ? 0 : 1).setListener(new AnimatorListenerAdapter() { 219 | @Override 220 | public void onAnimationEnd(Animator animation) { 221 | mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 222 | } 223 | }); 224 | 225 | mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 226 | mProgressView.animate().setDuration(shortAnimTime).alpha( 227 | show ? 1 : 0).setListener(new AnimatorListenerAdapter() { 228 | @Override 229 | public void onAnimationEnd(Animator animation) { 230 | mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 231 | } 232 | }); 233 | } else { 234 | // The ViewPropertyAnimator APIs are not available, so simply show 235 | // and hide the relevant UI components. 236 | mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 237 | mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 238 | } 239 | } 240 | 241 | @Override 242 | public Loader onCreateLoader(int i, Bundle bundle) { 243 | return new CursorLoader(this, 244 | // Retrieve data rows for the device user's 'profile' contact. 245 | Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI, 246 | ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION, 247 | 248 | // Select only email addresses. 249 | ContactsContract.Contacts.Data.MIMETYPE + 250 | " = ?", new String[]{ContactsContract.CommonDataKinds.Email 251 | .CONTENT_ITEM_TYPE}, 252 | 253 | // Show primary email addresses first. Note that there won't be 254 | // a primary email address if the user hasn't specified one. 255 | ContactsContract.Contacts.Data.IS_PRIMARY + " DESC"); 256 | } 257 | 258 | @Override 259 | public void onLoadFinished(Loader cursorLoader, Cursor cursor) { 260 | List emails = new ArrayList<>(); 261 | cursor.moveToFirst(); 262 | while (!cursor.isAfterLast()) { 263 | emails.add(cursor.getString(ProfileQuery.ADDRESS)); 264 | cursor.moveToNext(); 265 | } 266 | 267 | addEmailsToAutoComplete(emails); 268 | } 269 | 270 | @Override 271 | public void onLoaderReset(Loader cursorLoader) { 272 | 273 | } 274 | 275 | private void addEmailsToAutoComplete(List emailAddressCollection) { 276 | //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list. 277 | ArrayAdapter adapter = 278 | new ArrayAdapter<>(LoginActivity.this, 279 | android.R.layout.simple_dropdown_item_1line, emailAddressCollection); 280 | 281 | mEmailView.setAdapter(adapter); 282 | } 283 | 284 | 285 | private interface ProfileQuery { 286 | String[] PROJECTION = { 287 | ContactsContract.CommonDataKinds.Email.ADDRESS, 288 | ContactsContract.CommonDataKinds.Email.IS_PRIMARY, 289 | }; 290 | 291 | int ADDRESS = 0; 292 | int IS_PRIMARY = 1; 293 | } 294 | 295 | /** 296 | * Represents an asynchronous login/registration task used to authenticate 297 | * the user. 298 | */ 299 | public class UserLoginTask extends AsyncTask { 300 | 301 | private final String mEmail; 302 | private final String mPassword; 303 | 304 | UserLoginTask(String email, String password) { 305 | mEmail = email; 306 | mPassword = password; 307 | } 308 | 309 | @Override 310 | protected Boolean doInBackground(Void... params) { 311 | // TODO: attempt authentication against a network service. 312 | 313 | try { 314 | // Simulate network access. 315 | Thread.sleep(2000); 316 | } catch (InterruptedException e) { 317 | return false; 318 | } 319 | 320 | for (String credential : DUMMY_CREDENTIALS) { 321 | String[] pieces = credential.split(":"); 322 | if (pieces[0].equals(mEmail)) { 323 | // Account exists, return true if the password matches. 324 | return pieces[1].equals(mPassword); 325 | } 326 | } 327 | 328 | // TODO: register the new account here. 329 | return true; 330 | } 331 | 332 | @Override 333 | protected void onPostExecute(final Boolean success) { 334 | mAuthTask = null; 335 | showProgress(false); 336 | 337 | if (success) { 338 | finish(); 339 | } else { 340 | mPasswordView.setError(getString(R.string.error_incorrect_password)); 341 | mPasswordView.requestFocus(); 342 | } 343 | } 344 | 345 | @Override 346 | protected void onCancelled() { 347 | mAuthTask = null; 348 | showProgress(false); 349 | } 350 | } 351 | } 352 | 353 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/iview/IView.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.iview; 2 | 3 | /** 4 | * Created by raomengyang on 6/21/16. 5 | */ 6 | public interface IView { 7 | 8 | void showLoading(); 9 | 10 | void hideLoading(); 11 | } 12 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/iview/LoginView.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.iview; 2 | 3 | /** 4 | * Created by raomengyang on 6/21/16. 5 | */ 6 | public interface LoginView extends IView { 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/listener/OnLoginStatusListener.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.listener; 2 | 3 | /** 4 | * Created by raomengyang on 6/21/16. 5 | */ 6 | public interface OnLoginStatusListener { 7 | 8 | void onSendError(); 9 | 10 | void onSendSuccess(); 11 | 12 | void onCheckError(); 13 | 14 | void onCheckSuccess(); 15 | } 16 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/model/ILoginModel.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.model; 2 | 3 | import io.github.eterrao.androidmvp.listener.OnLoginStatusListener; 4 | 5 | /** 6 | * Created by raomengyang on 6/21/16. 7 | */ 8 | public interface ILoginModel { 9 | 10 | void sendMsg(String msg, OnLoginStatusListener onLoginStatusListener); 11 | 12 | void checkMsg(String msg, OnLoginStatusListener onLoginStatusListener); 13 | } 14 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/model/LoginModel.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.model; 2 | 3 | import io.github.eterrao.androidmvp.listener.OnLoginStatusListener; 4 | import io.github.eterrao.androidmvp.utils.HttpUtils; 5 | 6 | /** 7 | * Created by raomengyang on 6/21/16. 8 | */ 9 | public class LoginModel implements ILoginModel { 10 | 11 | @Override 12 | public void sendMsg(String msg, final OnLoginStatusListener onLoginStatusListener) { 13 | // TODO: send your msg code to server 14 | String yoursUrl = ""; 15 | String key = ""; 16 | String value = ""; 17 | HttpUtils.doPostRequest(yoursUrl, new RequestCallbackable() { 18 | @Override 19 | public void requestSuccess(Object object) { 20 | onLoginStatusListener.onSendSuccess(); 21 | } 22 | 23 | @Override 24 | public void requestError(Object object) { 25 | onLoginStatusListener.onSendError(); 26 | } 27 | }, 28 | key, value /*key1, value1, key2, value2...*/); 29 | } 30 | 31 | @Override 32 | public void checkMsg(String msg, OnLoginStatusListener onLoginStatusListener) { 33 | // TODO: check your msg code from server 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/model/RequestCallbackable.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.model; 2 | 3 | /** 4 | * Created by raomengyang on 6/21/16. 5 | */ 6 | public interface RequestCallbackable { 7 | 8 | void requestSuccess(T object); 9 | 10 | void requestError(T object); 11 | } 12 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/presenter/BasePresenter.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.presenter; 2 | 3 | import java.lang.ref.Reference; 4 | import java.lang.ref.WeakReference; 5 | 6 | /** 7 | * Created by raomengyang on 6/25/16. 8 | */ 9 | public abstract class BasePresenter implements Presenter { 10 | 11 | private Reference viewReference; 12 | 13 | @Override 14 | public void attachView(V view) { 15 | viewReference = new WeakReference(view); 16 | } 17 | 18 | protected V getView() { 19 | return viewReference.get(); 20 | } 21 | 22 | @Override 23 | public void detachView() { 24 | if (viewReference != null) { 25 | viewReference.clear(); 26 | viewReference = null; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/presenter/Presenter.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.presenter; 2 | 3 | /** 4 | * Created by raomengyang on 6/25/16. 5 | */ 6 | public interface Presenter { 7 | 8 | void attachView(V view); 9 | 10 | void detachView(); 11 | } 12 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/java/io/github/eterrao/androidmvp/utils/HttpUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.eterrao.androidmvp.utils; 2 | 3 | import io.github.eterrao.androidmvp.model.RequestCallbackable; 4 | 5 | /** 6 | * Created by raomengyang on 6/21/16. 7 | */ 8 | public class HttpUtils { 9 | 10 | public static void doPostRequest(String url, RequestCallbackable requestCallbackable, String... stringsKV) { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Blogs/AndroidMvp/AndroidMvp/app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 21 | 22 | 26 | 27 | 32 | 33 | 36 | 37 | 45 | 46 | 47 | 48 | 51 | 52 | 63 | 64 | 65 | 66 |