├── .gitignore ├── Android.md ├── HTTP请求和响应.xmind ├── Java.md ├── README.md ├── UML.mdj ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── nan │ │ └── androidreview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── test.html │ ├── java │ │ └── com │ │ │ └── nan │ │ │ └── androidreview │ │ │ ├── App.java │ │ │ ├── BitmapUtils.java │ │ │ ├── CacheManager.java │ │ │ ├── ConstraintLayoutActivity.java │ │ │ ├── ExceptionDemo.java │ │ │ ├── Fruit.java │ │ │ ├── HandlerThreadActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── Sample.java │ │ │ ├── TestFragment.java │ │ │ ├── TestIntentService.java │ │ │ ├── TestThread.java │ │ │ ├── TestType.java │ │ │ ├── dagger │ │ │ ├── Factory.java │ │ │ ├── FactoryActivity.java │ │ │ ├── FactoryActivityComponent.java │ │ │ └── Product.java │ │ │ ├── dagger_moudle │ │ │ ├── HttpActivity.java │ │ │ ├── HttpActivityComponent.java │ │ │ ├── HttpActivityModule.java │ │ │ ├── OkHttpClient.java │ │ │ └── RetrofitManager.java │ │ │ ├── designpattern │ │ │ ├── abstractfactory │ │ │ │ ├── AbstractFactory.java │ │ │ │ ├── ConcreteProductA1.java │ │ │ │ ├── ConcreteProductA2.java │ │ │ │ ├── ConcreteProductB1.java │ │ │ │ ├── ConcreteProductB2.java │ │ │ │ ├── Factory1.java │ │ │ │ ├── Factory2.java │ │ │ │ ├── ProductA.java │ │ │ │ └── ProductB.java │ │ │ ├── adapter │ │ │ │ ├── demo1 │ │ │ │ │ ├── Adaptee.java │ │ │ │ │ ├── Adapter.java │ │ │ │ │ ├── Client.java │ │ │ │ │ ├── ConcreteTarget.java │ │ │ │ │ └── Target.java │ │ │ │ └── demo2 │ │ │ │ │ ├── Adaptee.java │ │ │ │ │ ├── Adapter.java │ │ │ │ │ ├── Client.java │ │ │ │ │ ├── ConcreteTarget.java │ │ │ │ │ └── Target.java │ │ │ ├── bridge │ │ │ │ ├── Abstraction.java │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteImplementor1.java │ │ │ │ ├── ConcreteImplementor2.java │ │ │ │ ├── Implementor.java │ │ │ │ ├── RefineAbstraction1.java │ │ │ │ └── RefineAbstraction2.java │ │ │ ├── builder │ │ │ │ └── Product.java │ │ │ ├── chain │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteHandler1.java │ │ │ │ ├── ConcreteHandler2.java │ │ │ │ ├── ConcreteHandler3.java │ │ │ │ ├── Handler.java │ │ │ │ ├── Request.java │ │ │ │ └── Response.java │ │ │ ├── command │ │ │ │ ├── Client.java │ │ │ │ ├── Command.java │ │ │ │ ├── ConcreteCommand1.java │ │ │ │ ├── ConcreteCommand2.java │ │ │ │ ├── ConcreteReceiver1.java │ │ │ │ ├── ConcreteReceiver2.java │ │ │ │ ├── Invoker.java │ │ │ │ └── Receiver.java │ │ │ ├── composite │ │ │ │ ├── Client.java │ │ │ │ ├── Component.java │ │ │ │ ├── Composite.java │ │ │ │ └── Leaf.java │ │ │ ├── decorator │ │ │ │ ├── Client.java │ │ │ │ ├── Component.java │ │ │ │ ├── ConcreteComponent.java │ │ │ │ ├── ConcreteDecorator1.java │ │ │ │ ├── ConcreteDecorator2.java │ │ │ │ └── Decorator.java │ │ │ ├── facade │ │ │ │ ├── ClassA.java │ │ │ │ ├── ClassB.java │ │ │ │ ├── ClassC.java │ │ │ │ └── Facade.java │ │ │ ├── factorymethod │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteFactory.java │ │ │ │ ├── ConcreteProduct1.java │ │ │ │ ├── ConcreteProduct2.java │ │ │ │ ├── Factory.java │ │ │ │ └── Product.java │ │ │ ├── flyweight │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteFlyweight.java │ │ │ │ ├── Flyweight.java │ │ │ │ └── FlyweightFactory.java │ │ │ ├── interpreter │ │ │ │ ├── Client.java │ │ │ │ ├── Context.java │ │ │ │ ├── Expression.java │ │ │ │ ├── NonterminalExpression.java │ │ │ │ └── TerminalExpression.java │ │ │ ├── interpreter_demo │ │ │ │ ├── AddExpression.java │ │ │ │ ├── Calculator.java │ │ │ │ ├── Client.java │ │ │ │ ├── Expression.java │ │ │ │ ├── SubExpression.java │ │ │ │ ├── SymbolExpression.java │ │ │ │ └── VarExpression.java │ │ │ ├── iterator │ │ │ │ ├── Aggregate.java │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteAggregate.java │ │ │ │ ├── ConcreteIterator.java │ │ │ │ └── Iterator.java │ │ │ ├── mediator │ │ │ │ ├── Client.java │ │ │ │ ├── Colleague.java │ │ │ │ ├── ConcreteColleague1.java │ │ │ │ ├── ConcreteColleague2.java │ │ │ │ ├── ConcreteMediator.java │ │ │ │ └── Mediator.java │ │ │ ├── memento │ │ │ │ ├── Caretaker.java │ │ │ │ ├── Client.java │ │ │ │ ├── Memento.java │ │ │ │ └── Originator.java │ │ │ ├── observer │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteObserver.java │ │ │ │ ├── ConcreteSubject.java │ │ │ │ ├── Observer.java │ │ │ │ └── Subject.java │ │ │ ├── prototype │ │ │ │ ├── ConcretePrototype.java │ │ │ │ └── Prototype.java │ │ │ ├── proxy │ │ │ │ ├── demo1 │ │ │ │ │ ├── Client.java │ │ │ │ │ ├── RealSubject.java │ │ │ │ │ ├── Subject.java │ │ │ │ │ └── SubjectProxy.java │ │ │ │ └── demo2 │ │ │ │ │ ├── Client.java │ │ │ │ │ ├── RealSubject.java │ │ │ │ │ ├── Subject.java │ │ │ │ │ └── SubjectIH.java │ │ │ ├── singleton │ │ │ │ ├── demo1 │ │ │ │ │ └── Singleton.java │ │ │ │ ├── demo2 │ │ │ │ │ └── Singleton.java │ │ │ │ ├── demo3 │ │ │ │ │ └── Singleton.java │ │ │ │ ├── demo4 │ │ │ │ │ └── Singleton.java │ │ │ │ ├── demo5 │ │ │ │ │ └── Singleton.java │ │ │ │ ├── demo6 │ │ │ │ │ └── Singleton.java │ │ │ │ └── demo7 │ │ │ │ │ └── Singleton.kt │ │ │ ├── state │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteState1.java │ │ │ │ ├── ConcreteState2.java │ │ │ │ ├── Context.java │ │ │ │ └── State.java │ │ │ ├── strategy │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteStrategy1.java │ │ │ │ ├── ConcreteStrategy2.java │ │ │ │ ├── Context.java │ │ │ │ └── Strategy.java │ │ │ ├── templatemethod │ │ │ │ ├── AbstractClass.java │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteClass1.java │ │ │ │ └── ConcreteClass2.java │ │ │ └── visitor │ │ │ │ ├── Client.java │ │ │ │ ├── ConcreteElement1.java │ │ │ │ ├── ConcreteElement2.java │ │ │ │ ├── ConcreteVisitor1.java │ │ │ │ ├── ConcreteVisitor2.java │ │ │ │ ├── Element.java │ │ │ │ └── Visitor.java │ │ │ ├── leak │ │ │ ├── LeakActivity.java │ │ │ └── Utils.java │ │ │ └── net │ │ │ ├── TCPClient.java │ │ │ ├── TCPServer.java │ │ │ ├── UDPClient.java │ │ │ └── UDPServer.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_constraint_layout.xml │ │ ├── activity_factory.xml │ │ ├── activity_leak.xml │ │ ├── activity_main.xml │ │ └── activity_test1.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── nan │ └── androidreview │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lint ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── nan │ │ └── lint │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── nan │ │ │ └── lint │ │ │ ├── LogUtilDetector.java │ │ │ └── MyIssueRegistry.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── nan │ └── lint │ └── ExampleUnitTest.java ├── settings.gradle ├── 互联网协议.xmind ├── 未来计划.md ├── 浏览器输入URL之后 发生了什么.xmind ├── 计算机网络.md ├── 设计模式.mdj └── 设计模式与架构.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | -------------------------------------------------------------------------------- /HTTP请求和响应.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huannan/AndroidReview/e15f26864f71f55a14148065300b2d73858135ce/HTTP请求和响应.xmind -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 大纲: 2 | 3 | * [Java](https://github.com/huannan/AndroidReview/blob/master/Java.md) 4 | * [Android](https://github.com/huannan/AndroidReview/blob/master/Android.md) 5 | * [计算机网络](https://github.com/huannan/AndroidReview/blob/master/计算机网络.md) 6 | * [算法](https://github.com/huannan/AndroidReview/blob/master/算法.md) 7 | * [设计模式与架构](https://github.com/huannan/AndroidReview/blob/master/设计模式与架构.md) 8 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | 4 | android { 5 | compileSdkVersion 28 6 | defaultConfig { 7 | applicationId "com.nan.androidreview" 8 | minSdkVersion 15 9 | targetSdkVersion 28 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | 14 | javaCompileOptions { 15 | annotationProcessorOptions { 16 | arguments = [moduleName: project.getName()] 17 | } 18 | } 19 | } 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(include: ['*.jar'], dir: 'libs') 30 | implementation 'com.android.support:appcompat-v7:28.0.0' 31 | implementation 'com.android.support:support-v4:28.0.0' 32 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 33 | testImplementation 'junit:junit:4.12' 34 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 35 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 36 | implementation 'com.github.bumptech.glide:glide:4.7.1' 37 | annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1' 38 | implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' 39 | implementation 'io.reactivex.rxjava2:rxjava:2.0.7' 40 | implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar' 41 | //路由 42 | implementation 'com.alibaba:arouter-api:1.2.1.1' 43 | annotationProcessor 'com.alibaba:arouter-compiler:1.1.2.1' 44 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 45 | 46 | implementation 'com.google.dagger:dagger:2.10' 47 | annotationProcessor 'com.google.dagger:dagger-compiler:2.10' 48 | } 49 | repositories { 50 | mavenCentral() 51 | } 52 | 53 | ////配置lint的jar包 54 | //configurations { 55 | // lintJarImport 56 | //} 57 | // 58 | //dependencies { 59 | // lintJarImport project(path: ":lint", configuration: "lintJarOutput") 60 | //} 61 | // 62 | ////将jar复制到lint目录下的lint.jar,因为在 lint 命令执行时会检查该文件,存在的话会添加到 lint 检查的队列中 63 | //task copyLintJar(type: Copy) { 64 | // from(configurations.lintJarImport) { 65 | // rename { 66 | // String fileName -> 67 | // 'lint.jar' 68 | // } 69 | // } 70 | // into 'build/intermediates/lint/' 71 | //} 72 | // 73 | ////当 Project 创建完所有任务的有向图后,通过 afterEvaluate 函数设置一个回调 Closure。将 copyLintJar 插入到 compileLint 之前执行 74 | ////Closure 里,我 disable 了所有 Debug 的 Task 75 | //project.afterEvaluate { 76 | // def compileLintTask = project.tasks.find { it.name == 'compileLint' } 77 | // compileLintTask.dependsOn(copyLintJar) 78 | //} 79 | 80 | 81 | apply plugin: 'kotlin-android-extensions' 82 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/nan/androidreview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.nan.androidreview", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/assets/test.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huannan/AndroidReview/e15f26864f71f55a14148065300b2d73858135ce/app/src/main/assets/test.html -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/App.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.app.Application; 4 | import android.os.Build; 5 | 6 | import com.alibaba.android.arouter.launcher.ARouter; 7 | 8 | public class App extends Application { 9 | 10 | @Override 11 | public void onCreate() { 12 | super.onCreate(); 13 | 14 | ARouter.openLog(); 15 | if (BuildConfig.DEBUG) { 16 | // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险) 17 | ARouter.openDebug(); 18 | } 19 | // 尽可能早,推荐在Application中初始化 20 | ARouter.init(this); 21 | 22 | Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 23 | @Override 24 | public void uncaughtException(Thread t, Throwable e) { 25 | 26 | } 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/BitmapUtils.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.content.Context; 4 | import android.content.res.AssetManager; 5 | import android.content.res.Resources; 6 | import android.graphics.Bitmap; 7 | import android.graphics.BitmapFactory; 8 | import android.graphics.Canvas; 9 | import android.graphics.Matrix; 10 | import android.graphics.Paint; 11 | import android.graphics.PixelFormat; 12 | import android.graphics.PorterDuff; 13 | import android.graphics.PorterDuffXfermode; 14 | import android.graphics.Rect; 15 | import android.graphics.RectF; 16 | import android.graphics.drawable.BitmapDrawable; 17 | import android.graphics.drawable.Drawable; 18 | import android.media.ExifInterface; 19 | import android.text.TextUtils; 20 | import android.view.View; 21 | 22 | import java.io.BufferedOutputStream; 23 | import java.io.ByteArrayInputStream; 24 | import java.io.ByteArrayOutputStream; 25 | import java.io.File; 26 | import java.io.FileInputStream; 27 | import java.io.FileOutputStream; 28 | import java.io.IOException; 29 | import java.io.InputStream; 30 | 31 | public class BitmapUtils { 32 | 33 | /** 34 | * 从本地(SDcard)文件读取方式一 35 | * 36 | * @param filePath 文件路径 37 | * @param width 宽 38 | * @param height 高 39 | * @return 40 | */ 41 | public static Bitmap readBitmapFromFile(String filePath, int width, int height) { 42 | BitmapFactory.Options options = new BitmapFactory.Options(); 43 | options.inJustDecodeBounds = true; 44 | BitmapFactory.decodeFile(filePath, options); 45 | float srcWidth = options.outWidth; 46 | float srcHeight = options.outHeight; 47 | int inSampleSize = 1; 48 | 49 | if (srcHeight > height || srcWidth > width) { 50 | if (srcWidth > srcHeight) { 51 | inSampleSize = Math.round(srcHeight / height); 52 | } else { 53 | inSampleSize = Math.round(srcWidth / width); 54 | } 55 | } 56 | 57 | options.inJustDecodeBounds = false; 58 | options.inSampleSize = inSampleSize; 59 | 60 | return BitmapFactory.decodeFile(filePath, options); 61 | } 62 | 63 | /** 64 | * 从本地(SDcard)文件读取方式二 65 | * 66 | * @param filePath 文件路径 67 | * @param width 宽 68 | * @param height 高 69 | * @return 70 | */ 71 | public static Bitmap readBitmapFromFileDescriptor(String filePath, int width, int height) { 72 | try { 73 | FileInputStream fis = new FileInputStream(filePath); 74 | BitmapFactory.Options options = new BitmapFactory.Options(); 75 | options.inJustDecodeBounds = true; 76 | BitmapFactory.decodeFileDescriptor(fis.getFD(), null, options); 77 | float srcWidth = options.outWidth; 78 | float srcHeight = options.outHeight; 79 | int inSampleSize = 1; 80 | 81 | if (srcHeight > height || srcWidth > width) { 82 | if (srcWidth > srcHeight) { 83 | inSampleSize = Math.round(srcHeight / height); 84 | } else { 85 | inSampleSize = Math.round(srcWidth / width); 86 | } 87 | } 88 | 89 | options.inJustDecodeBounds = false; 90 | options.inSampleSize = inSampleSize; 91 | 92 | return BitmapFactory.decodeFileDescriptor(fis.getFD(), null, options); 93 | } catch (Exception ex) { 94 | } 95 | return null; 96 | } 97 | 98 | /** 99 | * 从输入流中读取文件(网络加载) 100 | * 101 | * @param ins 输入流 102 | * @param width 宽 103 | * @param height 高 104 | * @return 105 | */ 106 | public static Bitmap readBitmapFromInputStream(InputStream ins, int width, int height) { 107 | BitmapFactory.Options options = new BitmapFactory.Options(); 108 | options.inJustDecodeBounds = true; 109 | BitmapFactory.decodeStream(ins, null, options); 110 | float srcWidth = options.outWidth; 111 | float srcHeight = options.outHeight; 112 | int inSampleSize = 1; 113 | 114 | if (srcHeight > height || srcWidth > width) { 115 | if (srcWidth > srcHeight) { 116 | inSampleSize = Math.round(srcHeight / height); 117 | } else { 118 | inSampleSize = Math.round(srcWidth / width); 119 | } 120 | } 121 | 122 | options.inJustDecodeBounds = false; 123 | options.inSampleSize = inSampleSize; 124 | 125 | return BitmapFactory.decodeStream(ins, null, options); 126 | } 127 | 128 | /** 129 | * Res资源加载方式一。此种方式相当的耗费内存 建议采用decodeStream代替decodeResource 130 | * 131 | * @param resources 132 | * @param resourcesId 133 | * @param width 134 | * @param height 135 | * @return 136 | */ 137 | public static Bitmap readBitmapFromResource(Resources resources, int resourcesId, int width, int height) { 138 | BitmapFactory.Options options = new BitmapFactory.Options(); 139 | options.inJustDecodeBounds = true; 140 | BitmapFactory.decodeResource(resources, resourcesId, options); 141 | float srcWidth = options.outWidth; 142 | float srcHeight = options.outHeight; 143 | int inSampleSize = 1; 144 | 145 | if (srcHeight > height || srcWidth > width) { 146 | if (srcWidth > srcHeight) { 147 | inSampleSize = Math.round(srcHeight / height); 148 | } else { 149 | inSampleSize = Math.round(srcWidth / width); 150 | } 151 | } 152 | 153 | options.inJustDecodeBounds = false; 154 | options.inSampleSize = inSampleSize; 155 | 156 | return BitmapFactory.decodeResource(resources, resourcesId, options); 157 | } 158 | 159 | /** 160 | * Res资源加载方式二 161 | * 162 | * @param resources 163 | * @param resourcesId 164 | * @param width 165 | * @param height 166 | * @return 167 | */ 168 | public static Bitmap readBitmapFromResourceStream(Resources resources, int resourcesId, int width, int height) { 169 | InputStream ins = resources.openRawResource(resourcesId); 170 | BitmapFactory.Options options = new BitmapFactory.Options(); 171 | options.inJustDecodeBounds = true; 172 | BitmapFactory.decodeStream(ins, null, options); 173 | float srcWidth = options.outWidth; 174 | float srcHeight = options.outHeight; 175 | int inSampleSize = 1; 176 | 177 | if (srcHeight > height || srcWidth > width) { 178 | if (srcWidth > srcHeight) { 179 | inSampleSize = Math.round(srcHeight / height); 180 | } else { 181 | inSampleSize = Math.round(srcWidth / width); 182 | } 183 | } 184 | 185 | options.inJustDecodeBounds = false; 186 | options.inSampleSize = inSampleSize; 187 | 188 | return BitmapFactory.decodeStream(ins, null, options); 189 | } 190 | 191 | /** 192 | * Assets资源加载方式 193 | * 194 | * @param filePath 文件路径,即文件名称 195 | * @return 196 | */ 197 | public static Bitmap readBitmapFromAssetsFile(Context context, String filePath) { 198 | Bitmap image = null; 199 | AssetManager am = context.getResources().getAssets(); 200 | try { 201 | InputStream is = am.open(filePath); 202 | image = BitmapFactory.decodeStream(is); 203 | is.close(); 204 | } catch (IOException e) { 205 | e.printStackTrace(); 206 | } 207 | return image; 208 | } 209 | 210 | /** 211 | * 从二进制数据读取图片 212 | * 213 | * @param data 214 | * @param width 215 | * @param height 216 | * @return 217 | */ 218 | public static Bitmap readBitmapFromByteArray(byte[] data, int width, int height) { 219 | BitmapFactory.Options options = new BitmapFactory.Options(); 220 | options.inJustDecodeBounds = true; 221 | BitmapFactory.decodeByteArray(data, 0, data.length, options); 222 | float srcWidth = options.outWidth; 223 | float srcHeight = options.outHeight; 224 | int inSampleSize = 1; 225 | 226 | if (srcHeight > height || srcWidth > width) { 227 | if (srcWidth > srcHeight) { 228 | inSampleSize = Math.round(srcHeight / height); 229 | } else { 230 | inSampleSize = Math.round(srcWidth / width); 231 | } 232 | } 233 | 234 | options.inJustDecodeBounds = false; 235 | options.inSampleSize = inSampleSize; 236 | 237 | return BitmapFactory.decodeByteArray(data, 0, data.length, options); 238 | } 239 | 240 | /** 241 | * Drawable转化成Bitmap 242 | * 243 | * @param drawable 244 | * @return 245 | */ 246 | public static Bitmap drawableToBitmap(Drawable drawable) { 247 | Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); 248 | Canvas canvas = new Canvas(bitmap); 249 | drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 250 | drawable.draw(canvas); 251 | return bitmap; 252 | } 253 | 254 | /** 255 | * Bitmap转换成Drawable 256 | * 257 | * @param resources 258 | * @param bm 259 | * @return 260 | */ 261 | public static Drawable bitmapToDrawable(Resources resources, Bitmap bm) { 262 | Drawable drawable = new BitmapDrawable(resources, bm); 263 | return drawable; 264 | } 265 | 266 | /** 267 | * Bitmap转换成byte[] 268 | * 269 | * @param bm 270 | * @return 271 | */ 272 | public byte[] bitmap2Bytes(Bitmap bm) { 273 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 274 | bm.compress(Bitmap.CompressFormat.PNG, 100, baos); 275 | return baos.toByteArray(); 276 | } 277 | 278 | //byte[]转换成Bitmap 279 | //Bitmap bitmap = BitmapFactory.decodeByteArray(byte, 0, b.length); 280 | 281 | //InputStream转换成Bitmap 282 | //InputStream is = getResources().openRawResource(id); 283 | //Bitmap bitmap = BitmaoFactory.decodeStream(is); 284 | 285 | //InputStream转换成byte[] 286 | /* 287 | InputStream is = getResources().openRawResource(id);//也可以通过其他方式接收一个InputStream对象 288 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 289 | byte[] b = new byte[1024*2]; 290 | int len = 0; 291 | while ((len = is.read(b, 0, b.length)) != -1){ 292 | baos.write(b, 0, len); 293 | baos.flush(); 294 | } 295 | byte[] bytes = baos.toByteArray(); 296 | */ 297 | 298 | public static void writeBitmapToFile(String filePath, Bitmap b, int quality) { 299 | try { 300 | File desFile = new File(filePath); 301 | FileOutputStream fos = new FileOutputStream(desFile); 302 | BufferedOutputStream bos = new BufferedOutputStream(fos); 303 | b.compress(Bitmap.CompressFormat.JPEG, quality, bos); 304 | bos.flush(); 305 | bos.close(); 306 | } catch (IOException e) { 307 | e.printStackTrace(); 308 | } 309 | } 310 | 311 | private static Bitmap compressImage(Bitmap image) { 312 | if (image == null) { 313 | return null; 314 | } 315 | ByteArrayOutputStream baos = null; 316 | try { 317 | baos = new ByteArrayOutputStream(); 318 | image.compress(Bitmap.CompressFormat.JPEG, 100, baos); 319 | byte[] bytes = baos.toByteArray(); 320 | ByteArrayInputStream isBm = new ByteArrayInputStream(bytes); 321 | Bitmap bitmap = BitmapFactory.decodeStream(isBm); 322 | return bitmap; 323 | } catch (OutOfMemoryError e) { 324 | } finally { 325 | try { 326 | if (baos != null) { 327 | baos.close(); 328 | } 329 | } catch (IOException e) { 330 | } 331 | } 332 | return null; 333 | } 334 | 335 | /** 336 | * 根据scale生成一张图片 337 | * 338 | * @param bitmap 339 | * @param scale 等比缩放值 340 | * @return 341 | */ 342 | public static Bitmap bitmapScale(Bitmap bitmap, float scale) { 343 | Matrix matrix = new Matrix(); 344 | matrix.postScale(scale, scale); // 长和宽放大缩小的比例 345 | Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 346 | return resizeBmp; 347 | } 348 | 349 | /** 350 | * 读取照片exif信息中的旋转角度 351 | * 352 | * @param path 照片路径 353 | * @return角度 354 | */ 355 | private static int readPictureDegree(String path) { 356 | if (TextUtils.isEmpty(path)) { 357 | return 0; 358 | } 359 | int degree = 0; 360 | try { 361 | ExifInterface exifInterface = new ExifInterface(path); 362 | int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 363 | switch (orientation) { 364 | case ExifInterface.ORIENTATION_ROTATE_90: 365 | degree = 90; 366 | break; 367 | case ExifInterface.ORIENTATION_ROTATE_180: 368 | degree = 180; 369 | break; 370 | case ExifInterface.ORIENTATION_ROTATE_270: 371 | degree = 270; 372 | break; 373 | } 374 | } catch (Exception e) { 375 | } 376 | return degree; 377 | } 378 | 379 | private static Bitmap rotateBitmap(Bitmap b, float rotateDegree) { 380 | if (b == null) { 381 | return null; 382 | } 383 | Matrix matrix = new Matrix(); 384 | matrix.postRotate(rotateDegree); 385 | Bitmap rotaBitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true); 386 | return rotaBitmap; 387 | } 388 | 389 | // 通过图片id获得Bitmap: 390 | // Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); 391 | 392 | // 通过 assest 获取 获得Drawable bitmap: 393 | // InputStream in = this.getAssets().open("ic_launcher"); 394 | // Drawable da = Drawable.createFromStream(in, null); 395 | // Bitmap mm = BitmapFactory.decodeStream(in); 396 | // 397 | // 通过 sdcard 获得 bitmap 398 | // Bitmap bit = BitmapFactory.decodeFile("/sdcard/android.jpg"); 399 | 400 | 401 | public static Bitmap convertViewToBitmap(View view, int bitmapWidth, int bitmapHeight) { 402 | Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 403 | view.draw(new Canvas(bitmap)); 404 | return bitmap; 405 | } 406 | 407 | public static Bitmap convertViewToBitMap(View view) { 408 | // 打开图像缓存 409 | view.setDrawingCacheEnabled(true); 410 | // 必须调用measure和layout方法才能成功保存可视组件的截图到png图像文件 411 | // 测量View大小 412 | view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 413 | // 发送位置和尺寸到View及其所有的子View 414 | view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); 415 | // 获得可视组件的截图 416 | Bitmap bitmap = view.getDrawingCache(); 417 | return bitmap; 418 | } 419 | 420 | public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) { 421 | int width = bitmap.getWidth(); 422 | int height = bitmap.getHeight(); 423 | Matrix matrix = new Matrix(); 424 | float scaleWidht = ((float) w / width); 425 | float scaleHeight = ((float) h / height); 426 | matrix.postScale(scaleWidht, scaleHeight); 427 | Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); 428 | return newbmp; 429 | } 430 | 431 | /** 432 | * 获得圆角图片的方法 433 | * 434 | * @param bitmap 435 | * @param roundPx 436 | * @return 437 | */ 438 | public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) { 439 | 440 | Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap 441 | .getHeight(), Bitmap.Config.ARGB_8888); 442 | Canvas canvas = new Canvas(output); 443 | 444 | final int color = 0xff424242; 445 | final Paint paint = new Paint(); 446 | final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 447 | final RectF rectF = new RectF(rect); 448 | 449 | paint.setAntiAlias(true); 450 | canvas.drawARGB(0, 0, 0, 0); 451 | paint.setColor(color); 452 | canvas.drawRoundRect(rectF, roundPx, roundPx, paint); 453 | 454 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 455 | canvas.drawBitmap(bitmap, rect, rect, paint); 456 | 457 | return output; 458 | } 459 | 460 | /** 461 | * 对bitmap进行裁剪 462 | * 463 | * @param context 464 | * @param id 465 | * @param x 466 | * @param y 467 | * @return 468 | */ 469 | public Bitmap bitmapClip(Context context, int id, int x, int y) { 470 | Bitmap map = BitmapFactory.decodeResource(context.getResources(), id); 471 | map = Bitmap.createBitmap(map, x, y, 120, 120); 472 | return map; 473 | } 474 | 475 | public static Bitmap thumbnail(String path, int width, int height, boolean autoRotate) { 476 | 477 | //1. 获得Bitmap的宽高,但是不加载到内存 478 | BitmapFactory.Options options = new BitmapFactory.Options(); 479 | options.inJustDecodeBounds = true; 480 | BitmapFactory.decodeFile(path, options); 481 | int srcWidth = options.outWidth; 482 | int srcHeight = options.outHeight; 483 | 484 | //2. 计算图片缩放倍数 485 | int inSampleSize = 1; 486 | if (srcHeight > height || srcWidth > width) { 487 | if (srcWidth > srcHeight) { 488 | inSampleSize = Math.round(srcHeight / height); 489 | } else { 490 | inSampleSize = Math.round(srcWidth / width); 491 | } 492 | } 493 | 494 | //3. 真正加载图片到内存当中 495 | options.inJustDecodeBounds = false; 496 | options.inSampleSize = inSampleSize; 497 | options.inPreferredConfig = Bitmap.Config.RGB_565; 498 | options.inPurgeable = true; 499 | options.inInputShareable = true; 500 | return BitmapFactory.decodeFile(path, options); 501 | } 502 | 503 | } 504 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/CacheManager.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | 6 | import java.io.File; 7 | import java.math.BigDecimal; 8 | 9 | public class CacheManager { 10 | 11 | public static String getTotalCacheSize(Context context) throws Exception { 12 | long cacheSize = getFolderSize(context.getCacheDir()); 13 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 14 | cacheSize += getFolderSize(context.getExternalCacheDir()); 15 | } 16 | return getFormatSize(cacheSize); 17 | } 18 | 19 | 20 | public static void clearAllCache(Context context) { 21 | deleteDir(context.getCacheDir()); 22 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 23 | deleteDir(context.getExternalCacheDir()); 24 | } 25 | } 26 | 27 | private static boolean deleteDir(File dir) { 28 | if (dir != null && dir.isDirectory()) { 29 | String[] children = dir.list(); 30 | for (int i = 0; i < children.length; i++) { 31 | boolean success = deleteDir(new File(dir, children[i])); 32 | if (!success) { 33 | return false; 34 | } 35 | } 36 | } 37 | return dir.delete(); 38 | } 39 | 40 | // 获取文件 41 | //Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据 42 | //Context.getExternalCacheDir() --> SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据 43 | public static long getFolderSize(File file) throws Exception { 44 | long size = 0; 45 | try { 46 | File[] fileList = file.listFiles(); 47 | for (int i = 0; i < fileList.length; i++) { 48 | // 如果下面还有文件 49 | if (fileList[i].isDirectory()) { 50 | size = size + getFolderSize(fileList[i]); 51 | } else { 52 | size = size + fileList[i].length(); 53 | } 54 | } 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | return size; 59 | } 60 | 61 | /** 62 | * 格式化单位 63 | * 64 | * @param size 65 | * @return 66 | */ 67 | public static String getFormatSize(double size) { 68 | double kiloByte = size / 1024; 69 | if (kiloByte < 1) { 70 | // return size + "Byte"; 71 | return "0K"; 72 | } 73 | 74 | double megaByte = kiloByte / 1024; 75 | if (megaByte < 1) { 76 | BigDecimal result1 = new BigDecimal(Double.toString(kiloByte)); 77 | return result1.setScale(2, BigDecimal.ROUND_HALF_UP) 78 | .toPlainString() + "KB"; 79 | } 80 | 81 | double gigaByte = megaByte / 1024; 82 | if (gigaByte < 1) { 83 | BigDecimal result2 = new BigDecimal(Double.toString(megaByte)); 84 | return result2.setScale(2, BigDecimal.ROUND_HALF_UP) 85 | .toPlainString() + "MB"; 86 | } 87 | 88 | double teraBytes = gigaByte / 1024; 89 | if (teraBytes < 1) { 90 | BigDecimal result3 = new BigDecimal(Double.toString(gigaByte)); 91 | return result3.setScale(2, BigDecimal.ROUND_HALF_UP) 92 | .toPlainString() + "GB"; 93 | } 94 | BigDecimal result4 = new BigDecimal(teraBytes); 95 | return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() 96 | + "TB"; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/ConstraintLayoutActivity.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | 6 | public class ConstraintLayoutActivity extends AppCompatActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | setContentView(R.layout.activity_constraint_layout); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/ExceptionDemo.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import javax.xml.transform.Source; 4 | 5 | public class ExceptionDemo { 6 | 7 | public static void main(String[] args) { 8 | test4(); 9 | } 10 | 11 | public static void test1() { 12 | 13 | try { 14 | //System.exit(0); 15 | int i = 1/0; 16 | } catch (Exception e) { 17 | System.exit(0); 18 | }finally { 19 | System.out.println("finally"); 20 | } 21 | 22 | } 23 | 24 | 25 | public static int test2() { 26 | int a = 0; 27 | try { 28 | return a = 1; 29 | } catch (Exception e) { 30 | System.exit(0); 31 | }finally { 32 | a = 2; 33 | System.out.println("finally"); 34 | } 35 | return 0; 36 | } 37 | 38 | public static int test3() { 39 | int a = 0; 40 | try { 41 | return a = 1; 42 | } catch (Exception e) { 43 | 44 | }finally { 45 | a = 2; 46 | System.out.println("finally"); 47 | return a; 48 | } 49 | } 50 | 51 | public static void test4() { 52 | try { 53 | int a = 1/0; 54 | } catch (Exception e) { 55 | System.out.println("catch"); 56 | int b = 1 / 0; 57 | }finally { 58 | System.out.println("finally"); 59 | return; 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/Fruit.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | import java.lang.reflect.Field; 9 | 10 | public class Fruit { 11 | 12 | @Target(ElementType.FIELD) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Documented 15 | public @interface FruitName { 16 | 17 | String value() default ""; 18 | 19 | } 20 | 21 | @Target(ElementType.FIELD) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Documented 24 | public @interface FruitColor { 25 | 26 | enum Color {BLUE, RED, GREEN} 27 | 28 | Color value() default Color.GREEN; 29 | 30 | } 31 | 32 | @Target(ElementType.FIELD) 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @Documented 35 | public @interface FruitProvider { 36 | 37 | int id() default -1; 38 | 39 | String name() default ""; 40 | 41 | String address() default ""; 42 | } 43 | 44 | public class Apple { 45 | 46 | @FruitName("Apple") 47 | private String appleName; 48 | 49 | @FruitColor(FruitColor.Color.RED) 50 | private String appleColor; 51 | 52 | @FruitProvider(id = 1, name = "陕西红富士集团", address = "陕西省西安市延安路89号红富士大厦") 53 | private String appleProvider; 54 | 55 | public void setAppleColor(String appleColor) { 56 | this.appleColor = appleColor; 57 | } 58 | 59 | public String getAppleColor() { 60 | return appleColor; 61 | } 62 | 63 | public void setAppleName(String appleName) { 64 | this.appleName = appleName; 65 | } 66 | 67 | public String getAppleName() { 68 | return appleName; 69 | } 70 | 71 | public void setAppleProvider(String appleProvider) { 72 | this.appleProvider = appleProvider; 73 | } 74 | 75 | public String getAppleProvider() { 76 | return appleProvider; 77 | } 78 | 79 | public void displayName() { 80 | System.out.println("水果的名字是:苹果"); 81 | } 82 | } 83 | 84 | public static class FruitInfoUtil { 85 | public void getFruitInfo(Class clazz) { 86 | 87 | String strFruitName = " 水果名称:"; 88 | String strFruitColor = " 水果颜色:"; 89 | String strFruitProvicer = "供应商信息:"; 90 | 91 | Field[] fields = clazz.getDeclaredFields(); 92 | 93 | for (Field field : fields) { 94 | if (field.isAnnotationPresent(FruitName.class)) { 95 | FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class); 96 | strFruitName = strFruitName + fruitName.value(); 97 | System.out.println(strFruitName); 98 | } else if (field.isAnnotationPresent(FruitColor.class)) { 99 | FruitColor fruitColor = (FruitColor) field.getAnnotation(FruitColor.class); 100 | strFruitColor = strFruitColor + fruitColor.value().toString(); 101 | System.out.println(strFruitColor); 102 | } else if (field.isAnnotationPresent(FruitProvider.class)) { 103 | FruitProvider fruitProvider = (FruitProvider) field.getAnnotation(FruitProvider.class); 104 | strFruitProvicer = " 供应商编号:" + fruitProvider.id() + " 供应商名称:" + fruitProvider.name() + " 供应商地址:" + fruitProvider.address(); 105 | System.out.println(strFruitProvicer); 106 | } 107 | } 108 | } 109 | } 110 | 111 | public static void main(String[] args) { 112 | FruitInfoUtil util = new FruitInfoUtil(); 113 | util.getFruitInfo(Apple.class); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/HandlerThreadActivity.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.os.Bundle; 4 | import android.os.Handler; 5 | import android.os.HandlerThread; 6 | import android.os.Message; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.widget.TextView; 9 | 10 | import com.alibaba.android.arouter.facade.annotation.Route; 11 | 12 | @Route(path = "/com/a1") 13 | public class HandlerThreadActivity extends AppCompatActivity { 14 | 15 | private TextView tvMain; 16 | 17 | private HandlerThread mHandlerThread; 18 | //子线程中的handler 19 | private Handler mThreadHandler; 20 | //UI线程中的handler 21 | private Handler mMainHandler = new Handler(); 22 | 23 | //以防退出界面后Handler还在执行 24 | private boolean isUpdateInfo; 25 | //用以表示该handler的常量 26 | private static final int MSG_UPDATE_INFO = 0x110; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_test1); 32 | 33 | tvMain = (TextView) findViewById(R.id.tv_main); 34 | 35 | initThread(); 36 | } 37 | 38 | 39 | private void initThread() { 40 | mHandlerThread = new HandlerThread("check-message-coming"); 41 | mHandlerThread.start(); 42 | 43 | mThreadHandler = new Handler(mHandlerThread.getLooper()) { 44 | @Override 45 | public void handleMessage(Message msg) { 46 | update();//模拟数据更新 47 | 48 | if (isUpdateInfo) { 49 | //通过持有 HandlerThread的Looper 的 mThreadHandler去发送消息,触发HandlerThread工作 50 | mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO); 51 | } 52 | } 53 | }; 54 | 55 | } 56 | 57 | private void update() { 58 | try { 59 | //模拟耗时 60 | Thread.sleep(2000); 61 | mMainHandler.post(new Runnable() { 62 | @Override 63 | public void run() { 64 | String result = "每隔2秒更新一下数据:"; 65 | result += Math.random(); 66 | tvMain.setText(result); 67 | } 68 | }); 69 | 70 | } catch (InterruptedException e) { 71 | e.printStackTrace(); 72 | } 73 | 74 | } 75 | 76 | @Override 77 | protected void onResume() { 78 | super.onResume(); 79 | //开始查询 80 | isUpdateInfo = true; 81 | mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO); 82 | } 83 | 84 | @Override 85 | protected void onPause() { 86 | super.onPause(); 87 | //停止查询 88 | //以防退出界面后Handler还在执行 89 | isUpdateInfo = false; 90 | mThreadHandler.removeMessages(MSG_UPDATE_INFO); 91 | } 92 | 93 | @Override 94 | protected void onDestroy() { 95 | super.onDestroy(); 96 | //释放资源 97 | mHandlerThread.quit(); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.Manifest; 4 | import android.app.ActivityManager; 5 | import android.content.Context; 6 | import android.content.pm.PackageManager; 7 | import android.os.AsyncTask; 8 | import android.support.annotation.NonNull; 9 | import android.support.v4.app.ActivityCompat; 10 | import android.support.v4.app.Fragment; 11 | import android.support.v4.content.ContextCompat; 12 | import android.support.v7.app.AppCompatActivity; 13 | import android.os.Bundle; 14 | import android.util.Log; 15 | import android.view.View; 16 | import android.widget.TextView; 17 | import android.widget.Toast; 18 | 19 | import com.alibaba.android.arouter.launcher.ARouter; 20 | import com.bumptech.glide.Glide; 21 | import com.tbruyelle.rxpermissions2.Permission; 22 | import com.tbruyelle.rxpermissions2.RxPermissions; 23 | 24 | import io.reactivex.functions.Consumer; 25 | 26 | public class MainActivity extends AppCompatActivity { 27 | 28 | public static final String TAG = MainActivity.class.getSimpleName(); 29 | private TextView tv_test; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.activity_main); 35 | 36 | tv_test = findViewById(R.id.tv_test); 37 | 38 | //requestPermissions(); 39 | //testFragment(); 40 | //testAsyncTask(); 41 | //testIntentService(); 42 | //testMemory(); 43 | //testBitmap(); 44 | //testCache(); 45 | //testRouter(); 46 | testPermissions(); 47 | } 48 | 49 | public static final int CODE_READ_CONTACTS = 0x01; 50 | 51 | private void testPermissions() { 52 | 53 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) 54 | != PackageManager.PERMISSION_GRANTED) { 55 | 56 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, CODE_READ_CONTACTS); 57 | 58 | } else { 59 | 60 | Toast.makeText(this, "权限已经正确授予", Toast.LENGTH_SHORT).show(); 61 | 62 | } 63 | 64 | } 65 | 66 | @Override 67 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 68 | super.onRequestPermissionsResult(requestCode, permissions, grantResults); 69 | switch (requestCode) { 70 | case CODE_READ_CONTACTS: { 71 | if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 72 | 73 | // permission was granted, yay! Do the 74 | // contacts-related task you need to do. 75 | 76 | Toast.makeText(this, "权限已经正确授予", Toast.LENGTH_SHORT).show(); 77 | 78 | } else { 79 | 80 | // permission denied, boo! Disable the 81 | // functionality that depends on this permission. 82 | 83 | Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show(); 84 | } 85 | } 86 | } 87 | } 88 | 89 | private void testRouter() { 90 | tv_test.setOnClickListener(new View.OnClickListener() { 91 | @Override 92 | public void onClick(View v) { 93 | ARouter.getInstance() 94 | .build("/com/a1") 95 | .withInt("i", 1) 96 | .navigation(MainActivity.this, 100); 97 | } 98 | }); 99 | } 100 | 101 | private void testCache() { 102 | 103 | String cache = "0kb"; 104 | try { 105 | cache = CacheManager.getTotalCacheSize(this); 106 | } catch (Exception e) { 107 | e.printStackTrace(); 108 | } 109 | tv_test.setText(cache); 110 | 111 | } 112 | 113 | private void testBitmap() { 114 | 115 | //Glide.with(this).load() 116 | 117 | } 118 | 119 | private void requestPermissions() { 120 | RxPermissions rxPermission = new RxPermissions(this); 121 | rxPermission 122 | .requestEach(Manifest.permission.ACCESS_FINE_LOCATION, 123 | Manifest.permission.WRITE_EXTERNAL_STORAGE, 124 | Manifest.permission.READ_CALENDAR, 125 | Manifest.permission.READ_CALL_LOG, 126 | Manifest.permission.READ_CONTACTS, 127 | Manifest.permission.READ_PHONE_STATE, 128 | Manifest.permission.READ_SMS, 129 | Manifest.permission.RECORD_AUDIO, 130 | Manifest.permission.CAMERA, 131 | Manifest.permission.CALL_PHONE, 132 | Manifest.permission.SEND_SMS) 133 | .subscribe(new Consumer() { 134 | @Override 135 | public void accept(Permission permission) throws Exception { 136 | if (permission.granted) { 137 | // 用户已经同意该权限 138 | Log.d(TAG, permission.name + " is granted."); 139 | } else if (permission.shouldShowRequestPermissionRationale) { 140 | // 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框 141 | Log.d(TAG, permission.name + " is denied. More info should be provided."); 142 | } else { 143 | // 用户拒绝了该权限,并且选中『不再询问』 144 | Log.d(TAG, permission.name + " is denied."); 145 | } 146 | } 147 | }); 148 | } 149 | 150 | 151 | private void testMemory() { 152 | ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 153 | int memoryClass = am.getMemoryClass(); 154 | tv_test.setText(memoryClass + ""); 155 | } 156 | 157 | private void testIntentService() { 158 | 159 | } 160 | 161 | 162 | public void testFragment() { 163 | Fragment fragment = new TestFragment(); 164 | Bundle bundle = new Bundle(); 165 | bundle.putString("key", "value"); 166 | fragment.setArguments(bundle); 167 | getSupportFragmentManager().beginTransaction() 168 | .add(R.id.fragment_container, fragment, "test") 169 | .commit(); 170 | } 171 | 172 | public void tesetAsyncTask() { 173 | TestAsyncTask testAsyncTask = new TestAsyncTask(); 174 | testAsyncTask.execute("1", "2", "3"); 175 | } 176 | 177 | class TestAsyncTask extends AsyncTask { 178 | 179 | @Override 180 | protected void onPreExecute() { 181 | super.onPreExecute(); 182 | Log.i(TAG, "onPreExecute"); 183 | } 184 | 185 | @Override 186 | protected String doInBackground(String... strings) { 187 | 188 | StringBuilder sb = new StringBuilder(); 189 | 190 | for (int i = 0; i < strings.length; i++) { 191 | 192 | try { 193 | Thread.sleep(1000); 194 | } catch (InterruptedException e) { 195 | e.printStackTrace(); 196 | } 197 | 198 | sb.append(strings[i]); 199 | onProgressUpdate((i + 1) * 100 / strings.length); 200 | } 201 | 202 | return sb.toString(); 203 | } 204 | 205 | @Override 206 | protected void onProgressUpdate(Integer... values) { 207 | super.onProgressUpdate(values); 208 | Log.i(TAG, "onProgressUpdate: " + values[0]); 209 | } 210 | 211 | @Override 212 | protected void onPostExecute(String s) { 213 | super.onPostExecute(s); 214 | Log.i(TAG, "onPostExecute: " + s); 215 | } 216 | 217 | @Override 218 | protected void onCancelled(String s) { 219 | super.onCancelled(s); 220 | Log.i(TAG, "onCancelled: " + s); 221 | } 222 | } 223 | 224 | 225 | } -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/Sample.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Target; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public class Sample { 11 | 12 | @Target(ElementType.TYPE) 13 | public @interface Table { 14 | String tableName() default "name"; 15 | } 16 | 17 | @Documented 18 | @Table(tableName = "c1") 19 | public @interface NoDBColumn { 20 | 21 | } 22 | 23 | //因为类被new出来之后是存放在堆中的,所有成员变量全部存储于堆中(包括基本数据类型,引用和引用的对象实体) 24 | @NoDBColumn 25 | int i1 = 0; 26 | Sample s1 = new Sample(); 27 | 28 | public void method() { 29 | //局部变量和引用变量都是存在于栈中,但引用变量指向的对象是存在于堆中 30 | int i2 = 1; 31 | Sample s2 = new Sample(); 32 | } 33 | 34 | public static void main(String[] args) { 35 | //局部变量和引用变量都是存在于栈中,但引用变量指向的对象是存在于堆中 36 | Sample s3 = new Sample(); 37 | } 38 | 39 | 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/TestFragment.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | public class TestFragment extends Fragment { 12 | 13 | @Nullable 14 | @Override 15 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 16 | return inflater.inflate(R.layout.activity_main, container, false); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/TestIntentService.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import android.app.IntentService; 4 | import android.content.Intent; 5 | import android.support.annotation.Nullable; 6 | 7 | public class TestIntentService extends IntentService { 8 | 9 | public TestIntentService() { 10 | super("TestIntentService"); 11 | } 12 | 13 | 14 | @Override 15 | protected void onHandleIntent(@Nullable Intent intent) { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/TestThread.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import java.util.concurrent.ThreadPoolExecutor; 4 | 5 | public class TestThread { 6 | 7 | static int i1; int geti1() { return i1; } 8 | 9 | volatile int i2; int geti2() { return i2; } 10 | 11 | int i3; synchronized int geti3() { return i3; } 12 | 13 | public static void main(String[] args) { 14 | 15 | 16 | MyRunnable myRunnable = new MyRunnable("run 1"); 17 | 18 | Thread thread = new Thread(myRunnable); 19 | thread.start(); 20 | 21 | Error e; 22 | OutOfMemoryError error; 23 | } 24 | 25 | public synchronized void test1() { 26 | 27 | } 28 | 29 | public final void test2() { 30 | synchronized (this) { 31 | 32 | } 33 | } 34 | 35 | public final void test2(int i) { 36 | synchronized (this) { 37 | 38 | } 39 | } 40 | 41 | class MyThread extends Thread { 42 | 43 | @Override 44 | public void run() { 45 | super.run(); 46 | 47 | } 48 | } 49 | 50 | static class MyRunnable implements Runnable { 51 | 52 | volatile private String mName; 53 | 54 | public MyRunnable(String name) { 55 | mName = name; 56 | } 57 | 58 | @Override 59 | public void run() { 60 | try { 61 | Thread.sleep(1000); 62 | System.out.println(mName); 63 | } catch (Exception e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/TestType.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class TestType { 7 | 8 | T a[]; 9 | 10 | public static void main(String[] args) throws Exception { 11 | 12 | List list = new ArrayList<>(); 13 | list.getClass().getMethod("add", Object.class).invoke(list, "abc"); 14 | 15 | // List l1 = new ArrayList(); 16 | // List l2 = new ArrayList(); 17 | // l2 = l1; 18 | 19 | } 20 | 21 | public void print(List list) { 22 | Object o = list.get(0); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger/Factory.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger; 2 | 3 | import javax.inject.Inject; 4 | 5 | public class Factory { 6 | 7 | Product mProduct; 8 | 9 | @Inject 10 | public Factory(Product product) { 11 | mProduct = product; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger/FactoryActivity.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | 6 | import com.nan.androidreview.R; 7 | 8 | import javax.inject.Inject; 9 | 10 | public class FactoryActivity extends AppCompatActivity { 11 | 12 | @Inject 13 | Factory mFactory; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_factory); 19 | 20 | DaggerFactoryActivityComponent.create().inject(this); 21 | 22 | System.out.println(this.mFactory.mProduct.hashCode() + ""); 23 | 24 | } 25 | 26 | 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger/FactoryActivityComponent.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger; 2 | 3 | import dagger.Component; 4 | 5 | @Component 6 | public interface FactoryActivityComponent { 7 | void inject(FactoryActivity acy); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger/Product.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger; 2 | 3 | import javax.inject.Inject; 4 | 5 | public class Product { 6 | 7 | @Inject 8 | public Product() { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger_moudle/HttpActivity.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger_moudle; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | 6 | import com.nan.androidreview.R; 7 | 8 | import javax.inject.Inject; 9 | 10 | public class HttpActivity extends AppCompatActivity { 11 | 12 | @Inject 13 | RetrofitManager mRetrofitManager; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_factory); 19 | 20 | DaggerHttpActivityComponent.builder() 21 | .httpActivityModule(new HttpActivityModule(100)) 22 | .build() 23 | .inject(this); 24 | 25 | System.out.println(mRetrofitManager.getOkHttpClient().getCacheSize()); 26 | 27 | } 28 | 29 | 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger_moudle/HttpActivityComponent.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger_moudle; 2 | 3 | import dagger.Component; 4 | 5 | @Component(modules = {HttpActivityModule.class}) 6 | public interface HttpActivityComponent { 7 | 8 | void inject(HttpActivity acy); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger_moudle/HttpActivityModule.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger_moudle; 2 | 3 | import dagger.Module; 4 | import dagger.Provides; 5 | 6 | @Module 7 | public class HttpActivityModule { 8 | 9 | private int mCacheSize; 10 | 11 | public HttpActivityModule(int cacheSize) { 12 | mCacheSize = cacheSize; 13 | } 14 | 15 | @Provides 16 | OkHttpClient provideOkHttpClient() { 17 | OkHttpClient okHttpClient = new OkHttpClient(); 18 | okHttpClient.setCacheSize(mCacheSize); 19 | return okHttpClient; 20 | } 21 | 22 | @Provides 23 | RetrofitManager provideRetrofitManager(OkHttpClient client) { 24 | return new RetrofitManager(client); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger_moudle/OkHttpClient.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger_moudle; 2 | 3 | public class OkHttpClient { 4 | 5 | private int cacheSize; 6 | 7 | public OkHttpClient() { 8 | 9 | } 10 | 11 | public int getCacheSize() { 12 | return cacheSize; 13 | } 14 | 15 | public void setCacheSize(int cacheSize) { 16 | this.cacheSize = cacheSize; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/dagger_moudle/RetrofitManager.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.dagger_moudle; 2 | 3 | public class RetrofitManager { 4 | 5 | private OkHttpClient mOkHttpClient; 6 | 7 | public RetrofitManager(OkHttpClient okHttpClient) { 8 | mOkHttpClient = okHttpClient; 9 | } 10 | 11 | public OkHttpClient getOkHttpClient() { 12 | return mOkHttpClient; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/AbstractFactory.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public abstract class AbstractFactory { 4 | 5 | public abstract ProductA createProductA(); 6 | 7 | public abstract ProductB createProductB(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/ConcreteProductA1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public class ConcreteProductA1 extends ProductA { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/ConcreteProductA2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public class ConcreteProductA2 extends ProductA { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/ConcreteProductB1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public class ConcreteProductB1 extends ProductB { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/ConcreteProductB2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public class ConcreteProductB2 extends ProductB { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/Factory1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public class Factory1 extends AbstractFactory { 4 | 5 | @Override 6 | public ProductA createProductA() { 7 | return new ConcreteProductA1(); 8 | } 9 | 10 | @Override 11 | public ProductB createProductB() { 12 | return new ConcreteProductB1(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/Factory2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public class Factory2 extends AbstractFactory { 4 | 5 | @Override 6 | public ProductA createProductA() { 7 | return new ConcreteProductA2() { 8 | }; 9 | } 10 | 11 | @Override 12 | public ProductB createProductB() { 13 | return new ConcreteProductB2(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/ProductA.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public class ProductA { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/abstractfactory/ProductB.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.abstractfactory; 2 | 3 | public abstract class ProductB { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo1/Adaptee.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo1; 2 | 3 | public class Adaptee { 4 | 5 | //原有的业务逻辑 6 | public void volt220() { 7 | System.out.println("220V电压"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo1/Adapter.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo1; 2 | 3 | public class Adapter extends Adaptee implements Target { 4 | @Override 5 | public void volt5() { 6 | System.out.println("5V电压"); 7 | } 8 | 9 | public void volt220() { 10 | super.volt220(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo1/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo1; 2 | 3 | public class Client { 4 | public static void main(String[] args) { 5 | Target t1 = new ConcreteTarget(); 6 | t1.volt5(); 7 | 8 | Target t2 = new Adapter(); 9 | t2.volt5(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo1/ConcreteTarget.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo1; 2 | 3 | public class ConcreteTarget implements Target { 4 | @Override 5 | public void volt5() { 6 | System.out.println("5V电压"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo1/Target.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo1; 2 | 3 | public interface Target { 4 | 5 | void volt5(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo2/Adaptee.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo2; 2 | 3 | public class Adaptee { 4 | 5 | //原有的业务逻辑 6 | public void volt220() { 7 | System.out.println("220V电压"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo2/Adapter.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo2; 2 | 3 | public class Adapter implements Target { 4 | 5 | private Adaptee mAdaptee; 6 | 7 | public Adapter(Adaptee adaptee) { 8 | mAdaptee = adaptee; 9 | } 10 | 11 | @Override 12 | public void volt5() { 13 | System.out.println("5V电压"); 14 | } 15 | 16 | public void vol220() { 17 | mAdaptee.volt220(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo2/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo2; 2 | 3 | 4 | public class Client { 5 | public static void main(String[] args) { 6 | Target t1 = new ConcreteTarget(); 7 | t1.volt5(); 8 | 9 | Target t2 = new Adapter(new Adaptee()); 10 | t2.volt5(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo2/ConcreteTarget.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo2; 2 | 3 | public class ConcreteTarget implements Target { 4 | @Override 5 | public void volt5() { 6 | System.out.println("5V电压"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/adapter/demo2/Target.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.adapter.demo2; 2 | 3 | public interface Target { 4 | 5 | void volt5(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/bridge/Abstraction.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.bridge; 2 | 3 | /** 4 | * Abstraction是抽象化角色,保持实现化角色的引用 5 | * 这里的Abstraction代表咖啡 6 | */ 7 | public abstract class Abstraction { 8 | 9 | //抽象化角色,保持实现化角色的引用,是桥接模式的核心 10 | //这里的实现化角色代表调料 11 | private Implementor mImplementor; 12 | 13 | public Abstraction(Implementor implementor) { 14 | mImplementor = implementor; 15 | } 16 | 17 | public Implementor getImplementor() { 18 | return mImplementor; 19 | } 20 | 21 | /** 22 | * 冲咖啡,具体实现由子类实现 23 | */ 24 | public abstract void operator(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/bridge/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.bridge; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | 7 | Implementor i1 = new ConcreteImplementor1();//加糖 8 | Implementor i2 = new ConcreteImplementor1();//不加糖 9 | 10 | Abstraction a1 = new RefineAbstraction1(i1);//大杯、加糖 11 | Abstraction a2 = new RefineAbstraction1(i2);//大杯、不加糖 12 | Abstraction a3 = new RefineAbstraction2(i1);//小杯、加糖 13 | Abstraction a4 = new RefineAbstraction2(i2);//小杯、不加糖 14 | 15 | a1.operator(); 16 | a2.operator(); 17 | a3.operator(); 18 | a4.operator(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/bridge/ConcreteImplementor1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.bridge; 2 | 3 | /** 4 | * ConcreteImplementor具体的实现化角色 5 | * ConcreteImplementor咖啡的调料的实现类,代表加糖 6 | * 7 | */ 8 | public class ConcreteImplementor1 implements Implementor { 9 | @Override 10 | public String implement() { 11 | return "加糖"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/bridge/ConcreteImplementor2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.bridge; 2 | 3 | public class ConcreteImplementor2 implements Implementor { 4 | @Override 5 | public String implement() { 6 | return "不加糖"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/bridge/Implementor.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.bridge; 2 | 3 | /** 4 | * Implementor是实现化角色 5 | * 这里代表咖啡的调料,具体调料由实现类实现 6 | */ 7 | public interface Implementor { 8 | 9 | String implement(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/bridge/RefineAbstraction1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.bridge; 2 | 3 | /** 4 | * RefineAbstraction是修正抽象化角色,通过引用实现化角色Implementor对抽象化角色Abstraction进行修正 5 | * RefineAbstraction1是咖啡的实现类,代表大杯的咖啡 6 | */ 7 | public class RefineAbstraction1 extends Abstraction { 8 | 9 | public RefineAbstraction1(Implementor implementor) { 10 | super(implementor); 11 | } 12 | 13 | @Override 14 | public void operator() { 15 | System.out.println("大杯的" + this.getImplementor().implement() + "咖啡"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/bridge/RefineAbstraction2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.bridge; 2 | 3 | public class RefineAbstraction2 extends Abstraction { 4 | 5 | public RefineAbstraction2(Implementor implementor) { 6 | super(implementor); 7 | } 8 | 9 | @Override 10 | public void operator() { 11 | System.out.println("小杯的" + this.getImplementor().implement() + "咖啡"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/builder/Product.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.builder; 2 | 3 | public class Product { 4 | 5 | private String mPartA; 6 | private String mPartB; 7 | private String mPartC; 8 | 9 | public static class Builder{ 10 | 11 | Product mProduct; 12 | 13 | public Builder() { 14 | this.mProduct = new Product(); 15 | } 16 | 17 | public Builder buildPartA(String partA) { 18 | this.mProduct.mPartA = partA; 19 | return this; 20 | } 21 | 22 | public Builder buildPartB(String partB) { 23 | this.mProduct.mPartB = partB; 24 | return this; 25 | } 26 | 27 | public Builder buildPartC(String partC) { 28 | this.mProduct.mPartC = partC; 29 | return this; 30 | } 31 | 32 | public Product build() { 33 | return mProduct; 34 | } 35 | } 36 | 37 | 38 | public static void main(String[] args) { 39 | Product product = new Product.Builder() 40 | .buildPartA("a") 41 | .buildPartB("b") 42 | .buildPartC("c") 43 | .build(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/chain/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.chain; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Handler handler1 = new ConcreteHandler1(); 7 | Handler handler2 = new ConcreteHandler2(); 8 | Handler handler3 = new ConcreteHandler3(); 9 | 10 | //动态生成处理者的责任链 11 | handler1.setNextHandler(handler2); 12 | handler2.setNextHandler(handler3); 13 | 14 | //发送请求A 15 | Response response1 = handler1.handleRequest(new Request(1, "请求A")); 16 | System.out.println(response1.getReslust()); 17 | 18 | //发送请求B 19 | Response response2 = handler1.handleRequest(new Request(2, "请求B")); 20 | System.out.println(response2.getReslust()); 21 | 22 | //发送请求C 23 | Response response3 = handler1.handleRequest(new Request(3, "请求C")); 24 | System.out.println(response3.getReslust()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/chain/ConcreteHandler1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.chain; 2 | 3 | public class ConcreteHandler1 extends Handler { 4 | @Override 5 | protected int getHandlerLevel() { 6 | return 1; 7 | } 8 | 9 | @Override 10 | protected Response doSomething(Request request) { 11 | return new Response(this.getClass().getSimpleName() + "处理了" + request.getRequest()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/chain/ConcreteHandler2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.chain; 2 | 3 | public class ConcreteHandler2 extends Handler { 4 | @Override 5 | protected int getHandlerLevel() { 6 | return 2; 7 | } 8 | 9 | @Override 10 | protected Response doSomething(Request request) { 11 | return new Response(this.getClass().getSimpleName() + "处理了" + request.getRequest()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/chain/ConcreteHandler3.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.chain; 2 | 3 | public class ConcreteHandler3 extends Handler { 4 | @Override 5 | protected int getHandlerLevel() { 6 | return 3; 7 | } 8 | 9 | @Override 10 | protected Response doSomething(Request request) { 11 | return new Response(this.getClass().getSimpleName() + "处理了" + request.getRequest()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/chain/Handler.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.chain; 2 | 3 | /** 4 | * 抽象处理者 5 | * 抽象的处理者实现三个职责: 6 | * 1. 定义一个对外开放的请求的处理方法handleMessage模板方法 7 | * 2. 定义一个链的编排方法setNext,设置下一个处理者 8 | * 3. 定义了具体的请求者必须实现的两个方法:定义自己能够处理的级别getHandlerLevel和具体的处理任务doSomething方法 9 | */ 10 | public abstract class Handler { 11 | 12 | private Handler mNextHandler; 13 | 14 | public final Response handleRequest(Request request) { 15 | Response response; 16 | //判断是否是自己的处理级别 17 | if (request.getRequestLevel() == this.getHandlerLevel()) { 18 | response = this.doSomething(request); 19 | } else if (this.mNextHandler != null) { 20 | //不属于自己的处理级别,交给下一个处理 21 | response = this.mNextHandler.handleRequest(request); 22 | } else { 23 | //没有适当的处理者,业务自行处理 24 | response = new Response("没有适当的处理者"); 25 | } 26 | return response; 27 | } 28 | 29 | public void setNextHandler(Handler nextHandler) { 30 | this.mNextHandler = nextHandler; 31 | } 32 | 33 | protected abstract int getHandlerLevel(); 34 | 35 | protected abstract Response doSomething(Request request); 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/chain/Request.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.chain; 2 | 3 | /** 4 | * 请求体 5 | */ 6 | public class Request { 7 | 8 | //请求等级 9 | private int mRequestLevel; 10 | //请求参数 11 | private String mRequest; 12 | 13 | public Request(int requestLevel, String request) { 14 | this.mRequestLevel = requestLevel; 15 | this.mRequest = request; 16 | } 17 | 18 | public int getRequestLevel() { 19 | return this.mRequestLevel; 20 | } 21 | 22 | public String getRequest() { 23 | return this.mRequest; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/chain/Response.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.chain; 2 | 3 | /** 4 | * 相应 5 | */ 6 | public class Response { 7 | 8 | //相应内容 9 | private String mResult; 10 | 11 | public Response(String result) { 12 | this.mResult = result; 13 | } 14 | 15 | public String getReslust() { 16 | return this.mResult; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/command/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.command; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Invoker invoker = new Invoker(); 7 | 8 | invoker.setCommand(new ConcreteCommand1()); 9 | invoker.action(); 10 | 11 | invoker.setCommand(new ConcreteCommand2()); 12 | invoker.action(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/command/Command.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.command; 2 | 3 | /** 4 | * 命令角色:需要执行的所有命令都在这里声明。 5 | */ 6 | public abstract class Command { 7 | 8 | protected Receiver mReceiver; 9 | 10 | public Command(Receiver receiver) { 11 | this.mReceiver = receiver; 12 | } 13 | 14 | public abstract void execute(); 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/command/ConcreteCommand1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.command; 2 | 3 | /** 4 | * 例子:写代码的命令,下发给程序员 5 | */ 6 | public class ConcreteCommand1 extends Command { 7 | 8 | public ConcreteCommand1() { 9 | super(new ConcreteReceiver1()); 10 | } 11 | 12 | public ConcreteCommand1(Receiver receiver) { 13 | super(receiver); 14 | } 15 | 16 | @Override 17 | public void execute() { 18 | this.mReceiver.doSomething(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/command/ConcreteCommand2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.command; 2 | 3 | /** 4 | * 例子:设计UI的命令,下发给视觉设计师 5 | */ 6 | public class ConcreteCommand2 extends Command { 7 | 8 | public ConcreteCommand2() { 9 | super(new ConcreteReceiver2()); 10 | } 11 | 12 | public ConcreteCommand2(Receiver receiver) { 13 | super(receiver); 14 | } 15 | 16 | @Override 17 | public void execute() { 18 | this.mReceiver.doSomething(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/command/ConcreteReceiver1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.command; 2 | 3 | /** 4 | * 例子:程序员 5 | */ 6 | public class ConcreteReceiver1 extends Receiver{ 7 | 8 | @Override 9 | public void doSomething() { 10 | System.out.println("写代码"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/command/ConcreteReceiver2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.command; 2 | 3 | /** 4 | * 例子:视觉设计师 5 | */ 6 | public class ConcreteReceiver2 extends Receiver{ 7 | 8 | @Override 9 | public void doSomething() { 10 | System.out.println("设计UI"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/command/Invoker.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.command; 2 | 3 | /** 4 | * 调用者角色:接收客户端的命令,并执行命令。 5 | * 例子:项目经理 6 | */ 7 | public class Invoker { 8 | 9 | private Command mCommand; 10 | 11 | public void setCommand(Command command) { 12 | this.mCommand = command; 13 | } 14 | 15 | public void action() { 16 | this.mCommand.execute(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/command/Receiver.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.command; 2 | 3 | /** 4 | * 接收者角色:该角色就是干活的角色,命令传递到这里是应该被执行的。 5 | * 例子:程序员、视觉设计师的基类 6 | */ 7 | public abstract class Receiver { 8 | 9 | public abstract void doSomething(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/composite/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.composite; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Component c1 = new Composite("C盘"); 7 | Component c2 = new Composite("文件夹A"); 8 | Component c3 = new Leaf("文件A"); 9 | Component c4 = new Leaf("文件B"); 10 | 11 | c1.addChildren(c2); 12 | c1.addChildren(c3); 13 | c2.addChildren(c4); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/composite/Component.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.composite; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 抽象构件角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性 7 | * 例子:文件夹、文件的抽象 8 | */ 9 | public abstract class Component { 10 | 11 | /** 12 | * 结点名。例子:文件夹/文件的名字 13 | */ 14 | protected String mName; 15 | 16 | public Component(String name) { 17 | mName = name; 18 | } 19 | 20 | /** 21 | * 业务逻辑 22 | */ 23 | public abstract void doSomething(); 24 | 25 | /** 26 | * 添加结点。例子:添加文件夹/文件 27 | * @param component 28 | */ 29 | public abstract void addChildren(Component component); 30 | 31 | /** 32 | * 删除结点。例子:删除文件夹/文件 33 | * @param component 34 | */ 35 | public abstract void removeChildren(Component component); 36 | 37 | /** 38 | * 获取所有子结点。例子:获取所有子文件夹/文件 39 | * @return 40 | */ 41 | public abstract List getChildrens(); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/composite/Composite.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.composite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 树枝构件:树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。 8 | * 例子:文件夹 9 | */ 10 | public class Composite extends Component { 11 | 12 | private List mChildrens = new ArrayList<>(); 13 | 14 | public Composite(String name) { 15 | super(name); 16 | } 17 | 18 | @Override 19 | public void doSomething() { 20 | System.out.println("文件夹:" + this.mName); 21 | } 22 | 23 | @Override 24 | public void addChildren(Component component) { 25 | this.mChildrens.add(component); 26 | } 27 | 28 | @Override 29 | public void removeChildren(Component component) { 30 | this.mChildrens.remove(component); 31 | } 32 | 33 | @Override 34 | public List getChildrens() { 35 | return this.mChildrens; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/composite/Leaf.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.composite; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 叶子构件:叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。 7 | * 例子:文件 8 | */ 9 | public class Leaf extends Component { 10 | 11 | public Leaf(String name) { 12 | super(name); 13 | } 14 | 15 | @Override 16 | public void doSomething() { 17 | System.out.println("文件:" + this.mName); 18 | } 19 | 20 | @Override 21 | public void addChildren(Component component) { 22 | throw new UnsupportedOperationException("叶子结点不支持该操作"); 23 | } 24 | 25 | @Override 26 | public void removeChildren(Component component) { 27 | throw new UnsupportedOperationException("叶子结点不支持该操作"); 28 | } 29 | 30 | @Override 31 | public List getChildrens() { 32 | throw new UnsupportedOperationException("叶子结点不支持该操作"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/decorator/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.decorator; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Component component = new ConcreteDecorator1(new ConcreteDecorator2(new ConcreteComponent())); 7 | component.operate(); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/decorator/Component.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.decorator; 2 | 3 | public abstract class Component { 4 | 5 | public abstract void operate(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/decorator/ConcreteComponent.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.decorator; 2 | 3 | public class ConcreteComponent extends Component { 4 | 5 | @Override 6 | public void operate() { 7 | System.out.println("operate"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/decorator/ConcreteDecorator1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.decorator; 2 | 3 | public class ConcreteDecorator1 extends Decorator{ 4 | 5 | public ConcreteDecorator1(Component component) { 6 | super(component); 7 | } 8 | 9 | @Override 10 | public void operate() { 11 | decorate1(); 12 | super.operate(); 13 | } 14 | 15 | public void decorate1() { 16 | System.out.println("修饰方法1"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/decorator/ConcreteDecorator2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.decorator; 2 | 3 | public class ConcreteDecorator2 extends Decorator { 4 | 5 | public ConcreteDecorator2(Component component) { 6 | super(component); 7 | } 8 | 9 | @Override 10 | public void operate() { 11 | decorate2(); 12 | super.operate(); 13 | } 14 | 15 | public void decorate2() { 16 | System.out.println("修饰方法2"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/decorator/Decorator.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.decorator; 2 | 3 | public abstract class Decorator extends Component { 4 | 5 | private Component mComponent; 6 | 7 | public Decorator(Component component) { 8 | mComponent = component; 9 | } 10 | 11 | @Override 12 | public void operate() { 13 | //委托给被修饰者去执行对应的方法 14 | this.mComponent.operate(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/facade/ClassA.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.facade; 2 | 3 | public class ClassA { 4 | public void doSomethingA() { 5 | System.out.println("doSomethingA"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/facade/ClassB.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.facade; 2 | 3 | public class ClassB { 4 | public void doSomethingB() { 5 | System.out.println("doSomethingB"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/facade/ClassC.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.facade; 2 | 3 | public class ClassC { 4 | public void doSomethingC() { 5 | System.out.println("doSomethingC"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/facade/Facade.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.facade; 2 | 3 | public class Facade { 4 | 5 | ClassA mA = new ClassA(); 6 | ClassB mB = new ClassB(); 7 | ClassC mC = new ClassC(); 8 | 9 | public void methodA() { 10 | mA.doSomethingA(); 11 | } 12 | 13 | public void methodB() { 14 | mB.doSomethingB(); 15 | } 16 | 17 | public void methodC() { 18 | mC.doSomethingC(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/factorymethod/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.factorymethod; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | ConcreteFactory factory = new ConcreteFactory(); 7 | factory.createProduct(ConcreteProduct1.class); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/factorymethod/ConcreteFactory.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.factorymethod; 2 | 3 | /** 4 | * 具体工厂类 5 | */ 6 | public class ConcreteFactory extends Factory { 7 | @Override 8 | public T createProduct(Class clz) { 9 | Product product = null; 10 | try { 11 | product = (Product) Class.forName(clz.getName()).newInstance(); 12 | } catch (Exception e) { 13 | e.printStackTrace(); 14 | } 15 | return (T) product; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/factorymethod/ConcreteProduct1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.factorymethod; 2 | 3 | /** 4 | * 具体产品 5 | */ 6 | public class ConcreteProduct1 extends Product { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/factorymethod/ConcreteProduct2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.factorymethod; 2 | 3 | /** 4 | * 具体产品 5 | */ 6 | public class ConcreteProduct2 extends Product { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/factorymethod/Factory.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.factorymethod; 2 | 3 | /** 4 | * 抽象工厂类 5 | */ 6 | public abstract class Factory { 7 | 8 | public abstract T createProduct(Class clz); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/factorymethod/Product.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.factorymethod; 2 | 3 | /** 4 | * 抽象产品类 5 | */ 6 | public abstract class Product { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/flyweight/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.flyweight; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | 7 | for (int i = 0; i < 100; i++) { 8 | FlyweightFactory.getFlyweight("1"); 9 | } 10 | 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/flyweight/ConcreteFlyweight.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.flyweight; 2 | 3 | public class ConcreteFlyweight extends Flyweight { 4 | 5 | public ConcreteFlyweight(String extrinsic) { 6 | super(extrinsic); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/flyweight/Flyweight.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.flyweight; 2 | 3 | public abstract class Flyweight { 4 | 5 | //内部状态,可以共享的信息,存储在对象内部并且不会随环境改变 6 | private String mIntrinsic; 7 | 8 | //外部状态,不可以共享的信息,随着环境的改变而改变,是对象的索引值 9 | protected final String mExtrinsic; 10 | 11 | public Flyweight(String extrinsic) { 12 | mExtrinsic = extrinsic; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/flyweight/FlyweightFactory.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.flyweight; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class FlyweightFactory { 7 | 8 | //池容器 9 | private static Map sPool = new HashMap<>(); 10 | 11 | /** 12 | * 通过外部状态结合池来管理对象 13 | * @param extrinsic 14 | * @return 15 | */ 16 | public static Flyweight getFlyweight(String extrinsic) { 17 | 18 | Flyweight result = null; 19 | 20 | if (sPool.containsKey(extrinsic)) { 21 | result = sPool.get(extrinsic); 22 | } else { 23 | result = new ConcreteFlyweight(extrinsic); 24 | sPool.put(extrinsic, result); 25 | } 26 | 27 | return result; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter; 2 | 3 | import java.util.Stack; 4 | 5 | public class Client { 6 | public static void main(String[] args) { 7 | Context ctx = new Context(); 8 | //通常定一个语法容器,容纳一个具体的表达式,通常为ListArray、LinkedList、Stack等类型 9 | Stack stack = null; 10 | for(;;){ 11 | //进行语法判断,并产生递归调用 12 | } 13 | //产生一个完整的语法树,由各个具体的语法分析进行解析 14 | //Expression exp = stack.pop(); 15 | //具体元素进入场景 16 | //exp.interpreter(ctx); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter/Context.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter; 2 | 3 | public class Context { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter/Expression.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter; 2 | 3 | public abstract class Expression { 4 | public abstract Object interpreter(Context context); 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter/NonterminalExpression.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter; 2 | 3 | public class NonterminalExpression extends Expression { 4 | 5 | public NonterminalExpression(Expression... expressions) { 6 | 7 | } 8 | 9 | @Override 10 | public Object interpreter(Context context) { 11 | return null; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter/TerminalExpression.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter; 2 | 3 | public class TerminalExpression extends Expression { 4 | @Override 5 | public Object interpreter(Context context) { 6 | return null; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter_demo/AddExpression.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter_demo; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 加法 7 | */ 8 | public class AddExpression extends SymbolExpression { 9 | 10 | public AddExpression(Expression left, Expression right) { 11 | super(left, right); 12 | } 13 | 14 | @Override 15 | public int interpreter(HashMap var) { 16 | return this.mLeft.interpreter(var) + this.mRight.interpreter(var); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter_demo/Calculator.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter_demo; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStreamReader; 5 | import java.util.HashMap; 6 | import java.util.Stack; 7 | 8 | /** 9 | * 封装类 10 | */ 11 | public class Calculator { 12 | 13 | private Expression mExpression; 14 | 15 | //通过递归的方式来解析表达式 16 | public Calculator(String expStr) { 17 | Stack stack = new Stack<>(); 18 | char[] charArray = expStr.toCharArray(); 19 | 20 | Expression left; 21 | Expression right; 22 | 23 | for (int i = 0; i < charArray.length; i++) { 24 | switch (charArray[i]) { 25 | case '+': 26 | left = stack.pop(); 27 | right = new VarExpression(String.valueOf(charArray[++i])); 28 | stack.push(new AddExpression(left, right)); 29 | break; 30 | case '-': 31 | left = stack.pop(); 32 | right = new VarExpression(String.valueOf(charArray[++i])); 33 | stack.push(new SubExpression(left, right)); 34 | break; 35 | default: 36 | stack.push(new VarExpression(String.valueOf(charArray[i]))); 37 | break; 38 | } 39 | } 40 | //解析结果赋值给成员变量,通过calculate方法进行运算、得到计算结果 41 | this.mExpression = stack.pop(); 42 | } 43 | 44 | //计算结果 45 | public int calculate(HashMap var) { 46 | return this.mExpression.interpreter(var); 47 | } 48 | 49 | //获取表达式 50 | public static String getExpStr() throws Exception { 51 | System.out.println("请输入表达式:"); 52 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 53 | return reader.readLine(); 54 | } 55 | 56 | //为表达式中的运算符号赋值 57 | public static HashMap getValues(String expStr) throws Exception { 58 | HashMap values = new HashMap<>(); 59 | 60 | for (char ch : expStr.toCharArray()) { 61 | if (ch != '+' && ch != '-') { 62 | String key = String.valueOf(ch); 63 | 64 | //这里需要防止同样的元素被重复赋值导致值被覆盖 65 | if (!values.containsKey(key)) { 66 | System.out.println("请输入" + key + "的值:"); 67 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 68 | Integer value = Integer.valueOf(reader.readLine()); 69 | values.put(key, value); 70 | } 71 | } 72 | } 73 | 74 | return values; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter_demo/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter_demo; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Client { 6 | 7 | public static void main(String[] args) throws Exception { 8 | //获取表达式 9 | String expStr = Calculator.getExpStr(); 10 | //为表达式中的元素赋值,这里的HashMap充当了Context上下文角色 11 | HashMap values = Calculator.getValues(expStr); 12 | //构造Calculator,解析表达式 13 | Calculator calculator = new Calculator(expStr); 14 | //运算 15 | int result = calculator.calculate(values); 16 | 17 | System.out.println("计算结果为:" + result); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter_demo/Expression.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter_demo; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 抽象解释器(AbstractExpression) 7 | * 具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和NonterminalExpression完成 8 | */ 9 | public abstract class Expression { 10 | 11 | //每个表达式必须有一个解析任务 12 | public abstract int interpreter(HashMap var); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter_demo/SubExpression.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter_demo; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 减法 7 | */ 8 | public class SubExpression extends SymbolExpression { 9 | 10 | public SubExpression(Expression left, Expression right) { 11 | super(left, right); 12 | } 13 | 14 | @Override 15 | public int interpreter(HashMap var) { 16 | return this.mLeft.interpreter(var) - this.mRight.interpreter(var); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter_demo/SymbolExpression.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter_demo; 2 | 3 | /** 4 | * 非终结符表达式(NonterminalExpression) 5 | * 非终结符表达式又叫运算符号、做非终结符号 6 | * 运算符号就是加减符号,需要我们编写算法进行处理,每个运算符号都要对应处理单元,否则公式无法运行 7 | * 非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式 8 | */ 9 | public abstract class SymbolExpression extends Expression { 10 | 11 | //每个非终结符表达式都会对其他表达式产生依赖 12 | protected Expression mLeft; 13 | protected Expression mRight; 14 | 15 | public SymbolExpression(Expression left, Expression right) { 16 | this.mLeft = left; 17 | this.mRight = right; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/interpreter_demo/VarExpression.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.interpreter_demo; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 终结符表达式(TerminalExpression) 7 | * 终结符表达式又叫做运算元素、运算变量,也叫做终结符号,运算元素就是指a、b、c等符号,需要具体赋值的对象 8 | * 终结符:这些元素除了需要赋值外,不需要做任何处理。所有运算元素都对应一个具体的业务参数,这是语法中最小的单元逻辑,不可再拆分 9 | * 通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。 10 | */ 11 | public class VarExpression extends Expression { 12 | 13 | private String mKey; 14 | 15 | public VarExpression(String key) { 16 | this.mKey = key; 17 | } 18 | 19 | @Override 20 | public int interpreter(HashMap var) { 21 | return var.get(this.mKey); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/iterator/Aggregate.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.iterator; 2 | 3 | /** 4 | * 抽象容器:容器角色负责提供容器的基本操作、创建具体迭代器角色的接口,在Java中一般是iterator()方法。 5 | */ 6 | public interface Aggregate { 7 | void add(Object o); 8 | void remove(Object o); 9 | Iterator iterator(); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/iterator/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.iterator; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Aggregate agg = new ConcreteAggregate(); 7 | agg.add("a"); 8 | agg.add("b"); 9 | agg.add("c"); 10 | 11 | Iterator iterator = agg.iterator(); 12 | while (iterator.hasNext()) { 13 | System.out.println(iterator.next()); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/iterator/ConcreteAggregate.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.iterator; 2 | 3 | import java.util.Vector; 4 | 5 | /** 6 | * 具体容器 7 | */ 8 | public class ConcreteAggregate implements Aggregate { 9 | 10 | private Vector mVector = new Vector(); 11 | 12 | @Override 13 | public void add(Object o) { 14 | this.mVector.add(o); 15 | } 16 | 17 | @Override 18 | public void remove(Object o) { 19 | this.mVector.remove(o); 20 | } 21 | 22 | @Override 23 | public Iterator iterator() { 24 | return new ConcreteIterator(this.mVector); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/iterator/ConcreteIterator.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.iterator; 2 | 3 | import java.util.Vector; 4 | 5 | /** 6 | * 具体迭代器 7 | */ 8 | public class ConcreteIterator implements Iterator { 9 | 10 | private Vector mVector; 11 | //定义当前游标 12 | private int mCursor = 0; 13 | 14 | public ConcreteIterator(Vector vector) { 15 | this.mVector = vector; 16 | } 17 | 18 | @Override 19 | public Object next() { 20 | if (this.hasNext()) { 21 | return this.mVector.get(this.mCursor++); 22 | } else { 23 | return null; 24 | } 25 | } 26 | 27 | @Override 28 | public boolean hasNext() { 29 | if (this.mCursor == this.mVector.size()) { 30 | return false; 31 | } else { 32 | return true; 33 | } 34 | } 35 | 36 | @Override 37 | public boolean remove() { 38 | this.mVector.remove(this.mCursor); 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/iterator/Iterator.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.iterator; 2 | 3 | /** 4 | * 抽象迭代器:抽象迭代器负责定义访问和遍历元素的接口 5 | */ 6 | public interface Iterator { 7 | //遍历到下一个元素 8 | Object next(); 9 | //是否已经遍历到尾部 10 | boolean hasNext(); 11 | //删除当前指向的元素 12 | boolean remove(); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/mediator/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.mediator; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Mediator mediator = new ConcreteMediator(); 7 | ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator); 8 | ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator); 9 | mediator.setColleague1(colleague1); 10 | mediator.setColleague2(colleague2); 11 | 12 | //买房子 13 | colleague1.depMethod1(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/mediator/Colleague.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.mediator; 2 | 3 | /** 4 | * 同事类 5 | */ 6 | public abstract class Colleague { 7 | 8 | protected Mediator mMediator; 9 | 10 | public Colleague(Mediator mediator) { 11 | mMediator = mediator; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/mediator/ConcreteColleague1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.mediator; 2 | 3 | /** 4 | * 买家 5 | */ 6 | public class ConcreteColleague1 extends Colleague { 7 | 8 | public ConcreteColleague1(Mediator mediator) { 9 | super(mediator); 10 | } 11 | 12 | /** 13 | * 自发行为:同事本身的行为,例如改变对象自身的状态,处理自己的行为 14 | */ 15 | public void selfMethod1() { 16 | System.out.println("买家:付款,购买房子"); 17 | } 18 | 19 | /** 20 | * 依赖行为:自己不能完成的业务,必须依赖中介者才能完成的行为 21 | */ 22 | public void depMethod1() { 23 | System.out.println("买家:嘿,房产中介,我要买房"); 24 | //通知中介者,我要买房 25 | this.mMediator.doSomething1(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/mediator/ConcreteColleague2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.mediator; 2 | 3 | /** 4 | * 卖家 5 | */ 6 | public class ConcreteColleague2 extends Colleague { 7 | 8 | public ConcreteColleague2(Mediator mediator) { 9 | super(mediator); 10 | } 11 | 12 | public void selfMethod2() { 13 | System.out.println("卖家:嘿,房子整理中……房子整理好了"); 14 | } 15 | 16 | public void depMethod2() { 17 | System.out.println("卖家:嘿,房产中介,帮我告诉买家,房子整理好了,房子可以出售"); 18 | //通知中介者,房子可以出售 19 | this.mMediator.doSomething2(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/mediator/ConcreteMediator.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.mediator; 2 | 3 | /** 4 | * 例子:房产中介 5 | */ 6 | public class ConcreteMediator extends Mediator { 7 | 8 | @Override 9 | public void doSomething1() { 10 | System.out.println("房产中介:帮你找到卖家"); 11 | //通知卖家整理好房子 12 | this.mColleague2.selfMethod2(); 13 | this.mColleague2.depMethod2(); 14 | } 15 | 16 | @Override 17 | public void doSomething2() { 18 | System.out.println("房产中介:帮你找到买家"); 19 | this.mColleague1.selfMethod1(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/mediator/Mediator.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.mediator; 2 | 3 | /** 4 | * 中介者:协调各个同事角色,实现协作 5 | */ 6 | public abstract class Mediator { 7 | 8 | protected ConcreteColleague1 mColleague1; 9 | protected ConcreteColleague2 mColleague2; 10 | 11 | public abstract void doSomething1(); 12 | 13 | public abstract void doSomething2(); 14 | 15 | public ConcreteColleague1 getColleague1() { 16 | return mColleague1; 17 | } 18 | 19 | public void setColleague1(ConcreteColleague1 colleague1) { 20 | mColleague1 = colleague1; 21 | } 22 | 23 | public ConcreteColleague2 getColleague2() { 24 | return mColleague2; 25 | } 26 | 27 | public void setColleague2(ConcreteColleague2 colleague2) { 28 | mColleague2 = colleague2; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/memento/Caretaker.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.memento; 2 | 3 | /** 4 | * 备忘录管理员角色:对备忘录进行管理、保存和提供备忘录。实际开发中这个管理员角色一般会比较复杂。 5 | */ 6 | public class Caretaker { 7 | 8 | private Memento mMemento; 9 | 10 | public void setMemento(Memento memento) { 11 | this.mMemento = memento; 12 | } 13 | 14 | public Memento getMemento() { 15 | return this.mMemento; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/memento/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.memento; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Originator originator = new Originator(); 7 | Caretaker caretaker = new Caretaker(); 8 | 9 | originator.setState("状态1"); 10 | printState(originator); 11 | 12 | System.out.println("创建一个备忘录"); 13 | caretaker.setMemento(originator.createMemento()); 14 | 15 | System.out.println("修改状态"); 16 | originator.setState("状态2"); 17 | printState(originator); 18 | 19 | System.out.println("恢复一个备忘录"); 20 | originator.restoreMemento(caretaker.getMemento()); 21 | printState(originator); 22 | } 23 | 24 | public static void printState(Originator originator) { 25 | System.out.println("当前的状态:" + originator.getState()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/memento/Memento.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.memento; 2 | 3 | /** 4 | * 备忘录角色:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。 5 | */ 6 | public class Memento { 7 | 8 | private String mState; 9 | 10 | public Memento(String state) { 11 | this.mState = state; 12 | } 13 | 14 | public String getState() { 15 | return mState; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/memento/Originator.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.memento; 2 | 3 | /** 4 | * 发起人角色:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。 5 | */ 6 | public class Originator { 7 | 8 | private String mState = ""; 9 | 10 | public String getState() { 11 | return this.mState; 12 | } 13 | 14 | public void setState(String state) { 15 | this.mState = state; 16 | } 17 | 18 | /** 19 | * 创建一个备忘录 20 | * @return 21 | */ 22 | public Memento createMemento() { 23 | return new Memento(this.mState); 24 | } 25 | 26 | /** 27 | * 恢复一个备忘录 28 | * @param memento 29 | */ 30 | public void restoreMemento(Memento memento) { 31 | this.setState(memento.getState()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/observer/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.observer; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | ConcreteSubject subject = new ConcreteSubject(); 7 | Observer observer1 = new ConcreteObserver(); 8 | Observer observer2 = new ConcreteObserver(); 9 | 10 | subject.addObserver(observer1); 11 | subject.addObserver(observer2); 12 | 13 | subject.doSomething(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/observer/ConcreteObserver.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.observer; 2 | 3 | public class ConcreteObserver implements Observer { 4 | 5 | @Override 6 | public void update() { 7 | System.out.println("收到消息"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/observer/ConcreteSubject.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.observer; 2 | 3 | public class ConcreteSubject extends Subject { 4 | 5 | public void doSomething() { 6 | System.out.println("doSomething"); 7 | this.notifyObservers(); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/observer/Observer.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.observer; 2 | 3 | public interface Observer { 4 | 5 | void update(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/observer/Subject.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.observer; 2 | 3 | import java.util.Vector; 4 | 5 | public abstract class Subject { 6 | 7 | private Vector mObservers = new Vector<>(); 8 | 9 | public void addObserver(Observer o) { 10 | this.mObservers.add(o); 11 | } 12 | 13 | public void removeObserver(Observer o) { 14 | this.mObservers.remove(o); 15 | } 16 | 17 | public void notifyObservers() { 18 | for (Observer o : this.mObservers) { 19 | o.update(); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/prototype/ConcretePrototype.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.prototype; 2 | 3 | public class ConcretePrototype { 4 | 5 | @Override 6 | protected Object clone() { 7 | ConcretePrototype cp = null; 8 | try { 9 | cp = (ConcretePrototype) super.clone(); 10 | } catch (Exception e) { 11 | e.printStackTrace(); 12 | } 13 | return cp; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/prototype/Prototype.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.prototype; 2 | 3 | public abstract class Prototype implements Cloneable { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/proxy/demo1/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.proxy.demo1; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Subject subject = new SubjectProxy(new RealSubject()); 7 | subject.request(); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/proxy/demo1/RealSubject.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.proxy.demo1; 2 | 3 | public class RealSubject implements Subject { 4 | 5 | @Override 6 | public void request() { 7 | System.out.println("业务逻辑"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/proxy/demo1/Subject.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.proxy.demo1; 2 | 3 | public interface Subject { 4 | 5 | void request(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/proxy/demo1/SubjectProxy.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.proxy.demo1; 2 | 3 | public class SubjectProxy implements Subject { 4 | 5 | private Subject mSubject; 6 | 7 | public SubjectProxy(Subject subject) { 8 | mSubject = subject; 9 | } 10 | 11 | @Override 12 | public void request() { 13 | //代理中可以增加一些自定义的逻辑,这是面向切面编程的雏形 14 | before(); 15 | mSubject.request(); 16 | after(); 17 | } 18 | 19 | public void before() { 20 | System.out.println("before"); 21 | } 22 | 23 | public void after() { 24 | System.out.println("after"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/proxy/demo2/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.proxy.demo2; 2 | 3 | import java.lang.reflect.Proxy; 4 | 5 | public class Client { 6 | 7 | public static void main(String[] args) { 8 | 9 | RealSubject subject = new RealSubject(); 10 | 11 | //运行的时候动态产生一个代理对象,在实现阶段不用关心代理谁 12 | Subject proxy = (Subject) Proxy.newProxyInstance( 13 | subject.getClass().getClassLoader(), 14 | new Class[]{Subject.class}, 15 | new SubjectIH(subject)); 16 | 17 | proxy.request(); 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/proxy/demo2/RealSubject.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.proxy.demo2; 2 | 3 | public class RealSubject implements Subject { 4 | 5 | @Override 6 | public void request() { 7 | System.out.println("业务逻辑"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/proxy/demo2/Subject.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.proxy.demo2; 2 | 3 | public interface Subject { 4 | 5 | void request(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/proxy/demo2/SubjectIH.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.proxy.demo2; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | 6 | public class SubjectIH implements InvocationHandler { 7 | 8 | private Object mTarget; 9 | 10 | public SubjectIH(Object target) { 11 | mTarget = target; 12 | } 13 | 14 | @Override 15 | public Object invoke(Object o, Method method, Object[] args) throws Throwable { 16 | 17 | before(); 18 | 19 | Object res = method.invoke(this.mTarget, args); 20 | 21 | after(); 22 | 23 | if ("request".equals(method.getName())) { 24 | System.out.println("request!!"); 25 | } 26 | 27 | return res; 28 | } 29 | 30 | public void before() { 31 | System.out.println("before"); 32 | } 33 | 34 | public void after() { 35 | System.out.println("after"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/singleton/demo1/Singleton.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.singleton.demo1; 2 | 3 | /** 4 | * 懒汉式 5 | * 特点:Lazy初始化;线程安全,但是由于每次需要同步性能较低,不建议使用 6 | */ 7 | public class Singleton { 8 | 9 | private static Singleton sInstance; 10 | 11 | private Singleton() { 12 | 13 | } 14 | 15 | public static synchronized Singleton getInstance() { 16 | if (sInstance == null) { 17 | sInstance = new Singleton(); 18 | } 19 | return sInstance; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/singleton/demo2/Singleton.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.singleton.demo2; 2 | 3 | /** 4 | * 双检锁/双重校验锁(DCL,即 double-checked locking) 5 | * 特点:懒汉式的改进版,Lazy初始化;线程安全,且在多线程情况下能保持高性能 6 | */ 7 | public class Singleton { 8 | 9 | private static Singleton sInstance; 10 | 11 | private Singleton() { 12 | 13 | } 14 | 15 | public static Singleton getInstance() { 16 | if (sInstance == null) { 17 | synchronized (Singleton.class) { 18 | if (sInstance == null) { 19 | sInstance = new Singleton(); 20 | } 21 | } 22 | } 23 | return sInstance; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/singleton/demo3/Singleton.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.singleton.demo3; 2 | 3 | /** 4 | * 饿汉式 5 | * 特点:非Lazy初始化,浪费内存;线程安全,基于ClassLoader机制避免了多线程的同步问题 6 | */ 7 | public class Singleton { 8 | 9 | //方式一:类装载的时候初始化 10 | private static Singleton sInstance = new Singleton(); 11 | 12 | //方式二:类初始化的时候才去初始化 13 | static { 14 | sInstance = new Singleton(); 15 | } 16 | 17 | private Singleton() { 18 | 19 | } 20 | 21 | public static synchronized Singleton getInstance() { 22 | return sInstance; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/singleton/demo4/Singleton.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.singleton.demo4; 2 | 3 | /** 4 | * 静态内部类 5 | * 特点:饿汉式只要类装载或者类初始化的时候单例初始化,但是静态内部类的方式确保调用getInstance才Lazy初始化;线程安全;推荐使用 6 | */ 7 | public class Singleton { 8 | 9 | private static class SingletonHolder { 10 | private static final Singleton sInstance = new Singleton(); 11 | } 12 | 13 | private Singleton() { 14 | 15 | } 16 | 17 | public static Singleton getInstance() { 18 | return SingletonHolder.sInstance; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/singleton/demo5/Singleton.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.singleton.demo5; 2 | 3 | /** 4 | * 枚举 5 | * 特点:Lazy初始化;线程安全;这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。 6 | */ 7 | public enum Singleton { 8 | 9 | INSTANCE 10 | 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/singleton/demo6/Singleton.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.singleton.demo6; 2 | 3 | import android.support.annotation.Nullable; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * 通过容器来实现 10 | * 特点:通过特定时机(例如程序初始化)将单例注入到容器当中,使用的时候通过key来获取;降低了耦合度,提高易用性 11 | */ 12 | public class Singleton { 13 | 14 | public static class SingletonManager { 15 | 16 | private SingletonManager() { 17 | 18 | } 19 | 20 | private static Map sSingletonMap = new HashMap<>(); 21 | 22 | public static void register(String key, Singleton value) { 23 | if (!sSingletonMap.containsKey(key)) { 24 | sSingletonMap.put(key, value); 25 | } 26 | } 27 | 28 | public static void unregister(String key) { 29 | if (sSingletonMap.containsKey(key)) { 30 | sSingletonMap.remove(key); 31 | } 32 | } 33 | 34 | 35 | public static Singleton getSingleton(String key) { 36 | return sSingletonMap.get(key); 37 | } 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/singleton/demo7/Singleton.kt: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.singleton.demo7 2 | 3 | /** 4 | * Kotlin中通过object关键字可以实现最简单的单例 5 | * 特点:这种单例只有一个实现的对象;不能自定义构造方法;可以实现接口、继续父类 6 | */ 7 | object Singleton { 8 | public fun test() { 9 | println("") 10 | } 11 | } 12 | 13 | //调用方式 14 | fun main(args: Array) { 15 | Singleton.test() 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/state/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.state; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Context context = new Context(); 7 | System.out.println("当前状态:" + context.getCurrentState()); 8 | context.handle1(); 9 | System.out.println("当前状态:" + context.getCurrentState()); 10 | context.handle2(); 11 | System.out.println("当前状态:" + context.getCurrentState()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/state/ConcreteState1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.state; 2 | 3 | /** 4 | * 具体状态角色:每一个具体状态必须完成两个职责: 5 | * 1. 本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情。 6 | * 2. 以及本状态如何过渡到其他状态。 7 | */ 8 | public class ConcreteState1 extends State{ 9 | 10 | @Override 11 | public void handle1() { 12 | System.out.println("ConcreteState1下必须处理的逻辑"); 13 | } 14 | 15 | @Override 16 | public void handle2() { 17 | //本状态不能处理,需要切换状态,并且委托给下一个状态去处理 18 | System.out.println("当前状态" + this + "不能处理,切换到"+Context.STATE2); 19 | this.mContext.setCurrentState(Context.STATE2); 20 | this.mContext.handle2(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/state/ConcreteState2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.state; 2 | 3 | public class ConcreteState2 extends State{ 4 | 5 | @Override 6 | public void handle1() { 7 | System.out.println("当前状态" + this + "不能处理,切换到"+Context.STATE1); 8 | this.mContext.setCurrentState(Context.STATE1); 9 | this.mContext.handle1(); 10 | } 11 | 12 | @Override 13 | public void handle2() { 14 | 15 | System.out.println("ConcreteState2下必须处理的逻辑"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/state/Context.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.state; 2 | 3 | /** 4 | * 环境角色:定义客户端需要的接口,并且负责具体状态的切换。 5 | */ 6 | public class Context { 7 | 8 | //定义所有状态 9 | public static final State STATE1 = new ConcreteState1(); 10 | public static final State STATE2 = new ConcreteState2(); 11 | //当前状态 12 | private State mCurrentState; 13 | 14 | public Context() { 15 | //初始化 16 | STATE1.setContext(this); 17 | STATE2.setContext(this); 18 | this.mCurrentState = STATE1; 19 | } 20 | 21 | public State getCurrentState() { 22 | return this.mCurrentState; 23 | } 24 | 25 | public void setCurrentState(State state) { 26 | this.mCurrentState = state; 27 | } 28 | 29 | //行为委托给State去处理 30 | public void handle1() { 31 | this.mCurrentState.handle1(); 32 | } 33 | 34 | public void handle2() { 35 | this.mCurrentState.handle2(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/state/State.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.state; 2 | 3 | /** 4 | * 抽象状态角色:接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。 5 | */ 6 | public abstract class State { 7 | 8 | //抽象环境中声明一个环境角色,提供各个状态类自行访问。 9 | protected Context mContext; 10 | 11 | public void setContext(Context context) { 12 | this.mContext = context; 13 | } 14 | 15 | //提供所有状态的抽象行为,由各个实现类实现。 16 | public abstract void handle1(); 17 | public abstract void handle2(); 18 | 19 | @Override 20 | public String toString() { 21 | return this.getClass().getSimpleName(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/strategy/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.strategy; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | Strategy s1 = new ConcreteStrategy1(); 7 | Strategy s2 = new ConcreteStrategy2(); 8 | Context context = new Context(s1); 9 | 10 | context.doSomething(); 11 | 12 | context.setStrategy(s2); 13 | context.doSomething(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/strategy/ConcreteStrategy1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.strategy; 2 | 3 | /** 4 | * 具体策略角色 5 | * 实现抽象策略中的操作,该类含有具体的算法。 6 | */ 7 | public class ConcreteStrategy1 implements Strategy { 8 | @Override 9 | public void doSomething() { 10 | System.out.println("执行策略1"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/strategy/ConcreteStrategy2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.strategy; 2 | 3 | public class ConcreteStrategy2 implements Strategy { 4 | @Override 5 | public void doSomething() { 6 | System.out.println("执行策略2"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/strategy/Context.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.strategy; 2 | 3 | /** 4 | * Context封装角色:它也叫做上下文角色 5 | * 起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。 6 | */ 7 | public class Context { 8 | 9 | private Strategy mStrategy; 10 | 11 | public Context(Strategy strategy) { 12 | this.mStrategy = strategy; 13 | } 14 | 15 | public void setStrategy(Strategy strategy) { 16 | mStrategy = strategy; 17 | } 18 | 19 | public void doSomething() { 20 | this.mStrategy.doSomething(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/strategy/Strategy.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.strategy; 2 | 3 | /** 4 | * 抽象策略角色 5 | * 通常为接口,定义每个策略或算法必须具有的方法和属性。 6 | */ 7 | public interface Strategy { 8 | 9 | void doSomething(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/templatemethod/AbstractClass.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.templatemethod; 2 | 3 | /** 4 | * 抽象模板 5 | */ 6 | public abstract class AbstractClass { 7 | 8 | /** 9 | * 基本方法:基本方法也叫做基本操作,是由子类实现的方法,并且在模板方法被调用。 10 | */ 11 | protected abstract void method1(); 12 | 13 | protected abstract void method2(); 14 | 15 | /** 16 | * 钩子函数:子类可以通过钩子函数(Hook Method)约束父类的行为。 17 | * 18 | * @return 19 | */ 20 | protected abstract boolean hookMethod(); 21 | 22 | /** 23 | * 模板方法:可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。 24 | * 为了防止恶意的操作,一般模板方法都加上final关键字,不允许被覆写。 25 | */ 26 | public final void templateMethod() { 27 | method1(); 28 | if (hookMethod()) { 29 | method2(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/templatemethod/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.templatemethod; 2 | 3 | public class Client { 4 | 5 | public static void main(String[] args) { 6 | AbstractClass c1 = new ConcreteClass1(); 7 | AbstractClass c2 = new ConcreteClass2(); 8 | 9 | c1.templateMethod(); 10 | c2.templateMethod(); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/templatemethod/ConcreteClass1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.templatemethod; 2 | 3 | /** 4 | * 具体模板:实现父类所定义的一个或多个抽象方法,也就是父类定义的基本方法在子类中得以实现。 5 | */ 6 | public class ConcreteClass1 extends AbstractClass { 7 | @Override 8 | protected void method1() { 9 | System.out.println("ConcreteClass1 : method1"); 10 | } 11 | 12 | @Override 13 | protected void method2() { 14 | System.out.println("ConcreteClass1 : method2"); 15 | } 16 | 17 | @Override 18 | protected boolean hookMethod() { 19 | return true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/templatemethod/ConcreteClass2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.templatemethod; 2 | 3 | public class ConcreteClass2 extends AbstractClass { 4 | @Override 5 | protected void method1() { 6 | System.out.println("ConcreteClass2 : method1"); 7 | } 8 | 9 | @Override 10 | protected void method2() { 11 | System.out.println("ConcreteClass2 : method2"); 12 | } 13 | 14 | @Override 15 | protected boolean hookMethod() { 16 | return false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/visitor/Client.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.visitor; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Client { 7 | 8 | public static void main(String[] args) { 9 | //这里的List充当了UML中的ObjectStruture——结构对象,又叫元素产生者,一般容纳在多个不同类、不同接口的容器,如List、Set、Map等。 10 | //在项目中,一般很少抽象出这个角色。 11 | List elements = new ArrayList<>(); 12 | elements.add(new ConcreteElement1("A", "1")); 13 | elements.add(new ConcreteElement1("B", "2")); 14 | elements.add(new ConcreteElement2("C", "3")); 15 | elements.add(new ConcreteElement2("D", "4")); 16 | 17 | Visitor visitor1 = new ConcreteVisitor1(); 18 | Visitor visitor2 = new ConcreteVisitor2(); 19 | 20 | for (Element e : elements) { 21 | e.accept(visitor1); 22 | } 23 | 24 | System.out.println("-----------"); 25 | 26 | for (Element e : elements) { 27 | e.accept(visitor2); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/visitor/ConcreteElement1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.visitor; 2 | 3 | /** 4 | * 具体元素 5 | * 实现accept方法,通常是visitor.visit(this),基本上都形成了一种模式了 6 | */ 7 | public class ConcreteElement1 extends Element { 8 | 9 | public String mProperty1; 10 | 11 | public ConcreteElement1(String commonProperty, String property) { 12 | super(commonProperty); 13 | this.mProperty1 = property; 14 | } 15 | 16 | @Override 17 | public void accept(Visitor visitor) { 18 | visitor.visit(this); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/visitor/ConcreteElement2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.visitor; 2 | 3 | public class ConcreteElement2 extends Element { 4 | 5 | public String mProperty2; 6 | 7 | public ConcreteElement2(String commonProperty, String property) { 8 | super(commonProperty); 9 | this.mProperty2 = property; 10 | } 11 | 12 | @Override 13 | public void accept(Visitor visitor) { 14 | visitor.visit(this); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/visitor/ConcreteVisitor1.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.visitor; 2 | 3 | /** 4 | * 具体访问者 5 | * 影响访问者访问到一个类后该怎么干,要做什么事情。 6 | */ 7 | public class ConcreteVisitor1 implements Visitor { 8 | @Override 9 | public void visit(ConcreteElement1 element) { 10 | //注:这里的访问逻辑需要根据具体业务来定 11 | //一般来说,不同访问者对同一种元素类型有不同的访问方式 12 | System.out.println("ConcreteVisitor1:" + element.mCommonProperty); 13 | } 14 | 15 | @Override 16 | public void visit(ConcreteElement2 element) { 17 | System.out.println("ConcreteVisitor1:" + element.mCommonProperty); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/visitor/ConcreteVisitor2.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.visitor; 2 | 3 | public class ConcreteVisitor2 implements Visitor { 4 | @Override 5 | public void visit(ConcreteElement1 element) { 6 | System.out.println("ConcreteVisitor2:" + element.mProperty1); 7 | } 8 | 9 | @Override 10 | public void visit(ConcreteElement2 element) { 11 | System.out.println("ConcreteVisitor2:" + element.mProperty2); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/visitor/Element.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.visitor; 2 | 3 | /** 4 | * 抽象元素 5 | * 接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的 6 | */ 7 | public abstract class Element { 8 | 9 | public String mCommonProperty; 10 | 11 | public Element(String commonProperty) { 12 | mCommonProperty = commonProperty; 13 | } 14 | 15 | public abstract void accept(Visitor visitor); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/designpattern/visitor/Visitor.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.designpattern.visitor; 2 | 3 | /** 4 | * 抽象访问者 5 | * 抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象是可以被访问的 6 | */ 7 | public interface Visitor { 8 | void visit(ConcreteElement1 element); 9 | void visit(ConcreteElement2 element); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/leak/LeakActivity.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.leak; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | import com.nan.androidreview.R; 8 | 9 | public class LeakActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(@Nullable Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_leak); 15 | 16 | Utils utils = new Utils(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/leak/Utils.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.leak; 2 | 3 | 4 | import android.content.Context; 5 | 6 | public class Utils { 7 | 8 | private Context mContext; 9 | 10 | public Utils(Context context) { 11 | this.mContext = context; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/net/TCPClient.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.net; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | import java.io.OutputStream; 7 | import java.io.PrintWriter; 8 | import java.net.Socket; 9 | 10 | public class TCPClient { 11 | public static void main(String[] args) throws Exception { 12 | //客户端 13 | //1、创建客户端Socket,指定服务器地址和端口 14 | Socket socket = new Socket("localhost", 10086); 15 | //2、获取输出流,向服务器端发送信息 16 | OutputStream os = socket.getOutputStream();//字节输出流 17 | PrintWriter pw = new PrintWriter(os);//将输出流包装成打印流 18 | pw.write("用户名:admin;密码:123"); 19 | pw.flush(); 20 | socket.shutdownOutput(); 21 | //3、获取输入流,并读取服务器端的响应信息 22 | InputStream is = socket.getInputStream(); 23 | BufferedReader br = new BufferedReader(new InputStreamReader(is)); 24 | String info = null; 25 | while ((info = br.readLine()) != null) { 26 | System.out.println("我是客户端,服务器说:" + info); 27 | } 28 | //4、关闭资源 29 | br.close(); 30 | is.close(); 31 | pw.close(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/net/TCPServer.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.net; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | import java.io.OutputStream; 7 | import java.io.PrintWriter; 8 | import java.net.ServerSocket; 9 | import java.net.Socket; 10 | 11 | public class TCPServer { 12 | public static void main(String[] args) throws Exception { 13 | /** 14 | * 基于TCP协议的Socket通信,实现用户登录,服务端 15 | */ 16 | //1、创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 17 | ServerSocket serverSocket = new ServerSocket(10086);//1024-65535的某个端口 18 | //2、调用accept()方法开始监听,等待客户端的连接 19 | Socket socket = serverSocket.accept(); 20 | //3、获取输入流,并读取客户端信息 21 | InputStream is = socket.getInputStream(); 22 | InputStreamReader isr = new InputStreamReader(is); 23 | BufferedReader br = new BufferedReader(isr); 24 | String info = null; 25 | while ((info = br.readLine()) != null) { 26 | System.out.println("我是服务器,客户端说:" + info); 27 | } 28 | socket.shutdownInput();//关闭输入流 29 | //4、获取输出流,响应客户端的请求 30 | OutputStream os = socket.getOutputStream(); 31 | PrintWriter pw = new PrintWriter(os); 32 | pw.write("欢迎您!"); 33 | pw.flush(); 34 | //5、关闭资源 35 | pw.close(); 36 | os.close(); 37 | br.close(); 38 | isr.close(); 39 | is.close(); 40 | socket.close(); 41 | serverSocket.close(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/net/UDPClient.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.net; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | import java.io.OutputStream; 7 | import java.io.PrintWriter; 8 | import java.net.DatagramPacket; 9 | import java.net.DatagramSocket; 10 | import java.net.InetAddress; 11 | import java.net.Socket; 12 | 13 | public class UDPClient { 14 | public static void main(String[] args) throws Exception { 15 | //客户端 16 | //1、定义服务器的地址、端口号、数据 17 | InetAddress address = InetAddress.getByName("localhost"); 18 | int port = 10010; 19 | byte[] data = "用户名:admin;密码:123".getBytes(); 20 | //2、创建数据报,包含发送的数据信息 21 | DatagramPacket packet = new DatagramPacket(data, data.length, address, port); 22 | //3、创建DatagramSocket对象 23 | DatagramSocket socket = new DatagramSocket(); 24 | //4、向服务器发送数据 25 | socket.send(packet); 26 | 27 | 28 | //接受服务器端响应数据 29 | //====================================== 30 | //1、创建数据报,用于接受服务器端响应数据 31 | byte[] data2 = new byte[1024]; 32 | DatagramPacket packet2 = new DatagramPacket(data2, data2.length); 33 | //2、接受服务器响应的数据 34 | socket.receive(packet2); 35 | String reply = new String(data2, 0, packet2.getLength()); 36 | System.out.println("我是客户端,服务器说:" + reply); 37 | //4、关闭资源 38 | socket.close(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/nan/androidreview/net/UDPServer.java: -------------------------------------------------------------------------------- 1 | package com.nan.androidreview.net; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | import java.io.OutputStream; 7 | import java.io.PrintWriter; 8 | import java.net.DatagramPacket; 9 | import java.net.DatagramSocket; 10 | import java.net.InetAddress; 11 | import java.net.ServerSocket; 12 | import java.net.Socket; 13 | 14 | public class UDPServer { 15 | public static void main(String[] args) throws Exception { 16 | //服务器端,实现基于UDP的用户登录 17 | //1、创建服务器端DatagramSocket,指定端口 18 | DatagramSocket socket = new DatagramSocket(10010); 19 | //2、创建数据报,用于接受客户端发送的数据 20 | byte[] data = new byte[1024];// 21 | DatagramPacket packet = new DatagramPacket(data, data.length); 22 | //3、接受客户端发送的数据 23 | socket.receive(packet);//此方法在接受数据报之前会一致阻塞 24 | //4、读取数据 25 | String info = new String(data, 0, data.length); 26 | System.out.println("我是服务器,客户端告诉我" + info); 27 | 28 | //========================================================= 29 | //向客户端响应数据 30 | //1、定义客户端的地址、端口号、数据 31 | InetAddress address = packet.getAddress(); 32 | int port = packet.getPort(); 33 | byte[] data2 = "欢迎您!".getBytes(); 34 | //2、创建数据报,包含响应的数据信息 35 | DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port); 36 | //3、响应客户端 37 | socket.send(packet2); 38 | //4、关闭资源 39 | socket.close(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_constraint_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 |