├── 作业信息.txt ├── app ├── .gitignore ├── src │ ├── main │ │ ├── assets │ │ │ └── config.properties │ │ ├── res │ │ │ ├── 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 │ │ │ │ ├── ic_head_default_left.png │ │ │ │ └── ic_head_default_right.jpg │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── drawable-xhdpi │ │ │ │ ├── message_text_send.9.png │ │ │ │ └── message_text_receive.9.png │ │ │ ├── values │ │ │ │ ├── colors.xml │ │ │ │ ├── attrs.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── styles.xml │ │ │ │ ├── ids.xml │ │ │ │ └── strings.xml │ │ │ ├── drawable │ │ │ │ ├── message_shap_chat_bg.xml │ │ │ │ ├── side_nav_bar.xml │ │ │ │ ├── ic_menu_send.xml │ │ │ │ ├── ic_menu_slideshow.xml │ │ │ │ ├── ic_menu_gallery.xml │ │ │ │ ├── ic_menu_manage.xml │ │ │ │ ├── ic_menu_camera.xml │ │ │ │ └── ic_menu_share.xml │ │ │ ├── values-v21 │ │ │ │ └── styles.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── menu │ │ │ │ ├── main.xml │ │ │ │ └── activity_main_drawer.xml │ │ │ ├── layout │ │ │ │ ├── header_main.xml │ │ │ │ ├── backup.xml │ │ │ │ ├── item_text_send.xml │ │ │ │ ├── item_text_receive.xml │ │ │ │ ├── item_text_mvvm3.xml │ │ │ │ ├── item_text_mvvm.xml │ │ │ │ ├── item_text_mvvm2.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── activity_main_with_backup_btn.xml │ │ │ │ ├── activity_main_mvvm.xml │ │ │ │ ├── activity_main_mvvm3.xml │ │ │ │ ├── activity_main_mvvm2.xml │ │ │ │ └── login_main.xml │ │ │ └── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ ├── java │ │ │ └── nju │ │ │ │ └── androidchat │ │ │ │ └── client │ │ │ │ ├── mvvm0 │ │ │ │ ├── model │ │ │ │ │ ├── Direction.java │ │ │ │ │ ├── State.java │ │ │ │ │ └── ClientMessageObservable.java │ │ │ │ ├── viewmodel │ │ │ │ │ ├── UiOperator.java │ │ │ │ │ ├── ItemTextAdapters.java │ │ │ │ │ └── Mvvm0ViewModel.java │ │ │ │ └── Mvvm0TalkActivity.java │ │ │ │ ├── mvvm2 │ │ │ │ ├── model │ │ │ │ │ ├── Direction.java │ │ │ │ │ ├── State.java │ │ │ │ │ └── ClientMessageObservable.java │ │ │ │ ├── viewmodel │ │ │ │ │ ├── RecallHandler.java │ │ │ │ │ ├── LongClickListener.java │ │ │ │ │ ├── UiOperator.java │ │ │ │ │ ├── ItemTextAdapters.java │ │ │ │ │ └── Mvvm2ViewModel.java │ │ │ │ └── Mvvm2TalkActivity.java │ │ │ │ ├── mvvm3 │ │ │ │ ├── model │ │ │ │ │ ├── Direction.java │ │ │ │ │ ├── State.java │ │ │ │ │ └── ClientMessageObservable.java │ │ │ │ ├── viewmodel │ │ │ │ │ ├── UiOperator.java │ │ │ │ │ ├── CustomizedAdapters.java │ │ │ │ │ └── Mvvm3ViewModel.java │ │ │ │ └── Mvvm3TalkActivity.java │ │ │ │ ├── mvp0 │ │ │ │ ├── BasePresenter.java │ │ │ │ ├── BaseView.java │ │ │ │ ├── Mvp0Contract.java │ │ │ │ ├── Mvp0TalkPresenter.java │ │ │ │ ├── Mvp0TalkModel.java │ │ │ │ └── Mvp0TalkActivity.java │ │ │ │ ├── mvp1 │ │ │ │ ├── BasePresenter.java │ │ │ │ ├── BaseView.java │ │ │ │ ├── Mvp1BackupModel.java │ │ │ │ ├── Mvp1BackupPresenter.java │ │ │ │ ├── Mvp1Contract.java │ │ │ │ ├── Mvp1TalkPresenter.java │ │ │ │ ├── Mvp1BackupActivity.java │ │ │ │ ├── Mvp1TalkModel.java │ │ │ │ └── Mvp1TalkActivity.java │ │ │ │ ├── mvp2 │ │ │ │ ├── BasePresenter.java │ │ │ │ ├── BaseView.java │ │ │ │ ├── Mvp2Contract.java │ │ │ │ ├── Mvp2TalkPresenter.java │ │ │ │ ├── Mvp2TalkModel.java │ │ │ │ └── Mvp2TalkActivity.java │ │ │ │ ├── socket │ │ │ │ ├── MessageListener.java │ │ │ │ └── SocketClient.java │ │ │ │ ├── component │ │ │ │ ├── OnRecallMessageRequested.java │ │ │ │ ├── ItemTextReceive.java │ │ │ │ └── ItemTextSend.java │ │ │ │ ├── mvc1 │ │ │ │ ├── Mvc1BackupController.java │ │ │ │ ├── Mvc1TalkController.java │ │ │ │ ├── Mvc1BackupModel.java │ │ │ │ ├── Mvc1BackupActivity.java │ │ │ │ ├── Mvc1TalkModel.java │ │ │ │ └── Mvc1TalkActivity.java │ │ │ │ ├── mvc0 │ │ │ │ ├── Mvc0TalkController.java │ │ │ │ ├── Mvc0TalkModel.java │ │ │ │ └── Mvc0TalkActivity.java │ │ │ │ ├── ClientMessage.java │ │ │ │ ├── Utils.java │ │ │ │ └── MainActivity.java │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── nju │ │ │ └── androidchat │ │ │ └── client │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── nju │ │ └── androidchat │ │ └── client │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── server ├── .gitignore ├── src │ └── main │ │ └── java │ │ └── nju │ │ └── androidchat │ │ └── server │ │ ├── handlers │ │ ├── MessageHandler.java │ │ ├── DisconnectMessageHandler.java │ │ ├── RecallRequestMessageHandler.java │ │ └── ClientSendMessageHandler.java │ │ ├── ConnectionHandler.java │ │ └── ChatServer.java └── build.gradle ├── shared ├── .gitignore ├── src │ └── main │ │ └── java │ │ └── nju │ │ └── androidchat │ │ └── shared │ │ ├── message │ │ ├── DisconnectMessage.java │ │ ├── Message.java │ │ ├── RecallMessage.java │ │ ├── ErrorMessage.java │ │ ├── RecallRequestMessage.java │ │ ├── ClientSendMessage.java │ │ ├── LoginResponseMessage.java │ │ ├── ServerSendMessage.java │ │ └── LoginRequestMessage.java │ │ └── Shared.java └── build.gradle ├── settings.gradle ├── docs ├── 合作规范.md ├── img │ ├── frp1.png │ ├── mvc1.png │ ├── mvp1.png │ ├── mvvm1.png │ ├── extfunc1.gif │ ├── extfunc2.gif │ ├── extfunc3.gif │ ├── extfunc4.gif │ ├── differences.png │ ├── frp-message.png │ ├── frp-badwords.png │ ├── frp-throttle.png │ ├── client-chat-main.png │ ├── server-launched.png │ ├── mvc-send-dataflow.png │ ├── client-input-username.png │ ├── mvc-backup-dataflow.png │ ├── mvp-backup-dataflow.png │ ├── mvp-return-dataflow.png │ └── mvvm-return-dataflow.png ├── 客户端和服务器端通信.md └── 扩展需求开发文档.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .idea ├── encodings.xml ├── vcs.xml ├── compiler.xml ├── misc.xml ├── runConfigurations │ ├── Start_all.xml │ ├── Server.xml │ ├── app1.xml │ └── app2.xml └── gradle.xml ├── 作业提交说明.md ├── gradle.properties ├── gradlew.bat ├── .gitignore └── gradlew /作业信息.txt: -------------------------------------------------------------------------------- 1 | 学号: 2 | 作业选项: -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /shared/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':server', ':shared' 2 | -------------------------------------------------------------------------------- /docs/合作规范.md: -------------------------------------------------------------------------------- 1 | # 合作规范 2 | 3 | 每个人在master目前的最新之下创建自己的分支,在自己的分支中工作,工作完成后将分支合并到master中去。 -------------------------------------------------------------------------------- /app/src/main/assets/config.properties: -------------------------------------------------------------------------------- 1 | chat_activity=nju.androidchat.client.frp4.Frp4TalkActivity -------------------------------------------------------------------------------- /docs/img/frp1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/frp1.png -------------------------------------------------------------------------------- /docs/img/mvc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/mvc1.png -------------------------------------------------------------------------------- /docs/img/mvp1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/mvp1.png -------------------------------------------------------------------------------- /docs/img/mvvm1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/mvvm1.png -------------------------------------------------------------------------------- /docs/img/extfunc1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/extfunc1.gif -------------------------------------------------------------------------------- /docs/img/extfunc2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/extfunc2.gif -------------------------------------------------------------------------------- /docs/img/extfunc3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/extfunc3.gif -------------------------------------------------------------------------------- /docs/img/extfunc4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/extfunc4.gif -------------------------------------------------------------------------------- /docs/img/differences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/differences.png -------------------------------------------------------------------------------- /docs/img/frp-message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/frp-message.png -------------------------------------------------------------------------------- /docs/img/frp-badwords.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/frp-badwords.png -------------------------------------------------------------------------------- /docs/img/frp-throttle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/frp-throttle.png -------------------------------------------------------------------------------- /docs/img/client-chat-main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/client-chat-main.png -------------------------------------------------------------------------------- /docs/img/server-launched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/server-launched.png -------------------------------------------------------------------------------- /docs/img/mvc-send-dataflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/mvc-send-dataflow.png -------------------------------------------------------------------------------- /docs/img/client-input-username.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/client-input-username.png -------------------------------------------------------------------------------- /docs/img/mvc-backup-dataflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/mvc-backup-dataflow.png -------------------------------------------------------------------------------- /docs/img/mvp-backup-dataflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/mvp-backup-dataflow.png -------------------------------------------------------------------------------- /docs/img/mvp-return-dataflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/mvp-return-dataflow.png -------------------------------------------------------------------------------- /docs/img/mvvm-return-dataflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/docs/img/mvvm-return-dataflow.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm0/model/Direction.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm0.model; 2 | 3 | public enum Direction { 4 | SEND, RECEIVE 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm0/model/State.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm0.model; 2 | 3 | public enum State { 4 | SENT,WITHDRAWN,FAILED 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm2/model/Direction.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm2.model; 2 | 3 | public enum Direction { 4 | SEND, RECEIVE 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm2/model/State.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm2.model; 2 | 3 | public enum State { 4 | SENT,WITHDRAWN,FAILED 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm3/model/Direction.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm3.model; 2 | 3 | public enum Direction { 4 | SEND, RECEIVE 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm3/model/State.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm3.model; 2 | 3 | public enum State { 4 | SENT,WITHDRAWN,FAILED 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_head_default_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-xhdpi/ic_head_default_left.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/message_text_send.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/drawable-xhdpi/message_text_send.9.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_head_default_right.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/mipmap-xhdpi/ic_head_default_right.jpg -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvp0/BasePresenter.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvp0; 2 | 3 | public interface BasePresenter { 4 | 5 | void start(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvp1/BasePresenter.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvp1; 2 | 3 | public interface BasePresenter { 4 | 5 | void start(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvp2/BasePresenter.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvp2; 2 | 3 | public interface BasePresenter { 4 | 5 | void start(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/message_text_receive.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddadaal/android-chat-in-4-patterns/HEAD/app/src/main/res/drawable-xhdpi/message_text_receive.9.png -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvp0/BaseView.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvp0; 2 | 3 | public interface BaseView { 4 | 5 | void setPresenter(T presenter); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvp1/BaseView.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvp1; 2 | 3 | public interface BaseView { 4 | 5 | void setPresenter(T presenter); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvp2/BaseView.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvp2; 2 | 3 | public interface BaseView { 4 | 5 | void setPresenter(T presenter); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/DisconnectMessage.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | 3 | /** 4 | * 客户端到服务器:断开连接 5 | */ 6 | public class DisconnectMessage extends Message { 7 | } 8 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/Message.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | 3 | import java.io.Serializable; 4 | 5 | public abstract class Message implements Serializable { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/Shared.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared; 2 | 3 | 4 | import lombok.Getter; 5 | 6 | public class Shared { 7 | 8 | public static final int SERVER_PORT = 16492; 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm0/viewmodel/UiOperator.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm0.viewmodel; 2 | 3 | public interface UiOperator { 4 | void runOnUiThread(Runnable action); 5 | void scrollListToBottom(); 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/socket/MessageListener.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.socket; 2 | 3 | import nju.androidchat.shared.message.Message; 4 | 5 | public interface MessageListener { 6 | void onMessageReceived(Message message); 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/component/OnRecallMessageRequested.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.component; 2 | 3 | import java.util.UUID; 4 | 5 | public interface OnRecallMessageRequested { 6 | void onRecallMessageRequested(UUID messageId); 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm3/viewmodel/UiOperator.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm3.viewmodel; 2 | 3 | public interface UiOperator { 4 | void runOnUiThread(Runnable action); 5 | void scrollListToBottom(); 6 | void sendBadWordNotice(); 7 | } 8 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/message_shap_chat_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed May 08 14:11:32 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm2/viewmodel/RecallHandler.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm2.viewmodel; 2 | 3 | import nju.androidchat.client.mvvm2.model.ClientMessageObservable; 4 | 5 | public interface RecallHandler { 6 | void handleRecall(ClientMessageObservable messageObservable); 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm2/viewmodel/LongClickListener.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm2.viewmodel; 2 | 3 | import nju.androidchat.client.mvvm2.model.ClientMessageObservable; 4 | 5 | public interface LongClickListener { 6 | boolean onLongClick(ClientMessageObservable messageObservable); 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /shared/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | 3 | dependencies { 4 | 5 | compileOnly 'org.projectlombok:lombok:1.18.8' 6 | annotationProcessor 'org.projectlombok:lombok:1.18.8' 7 | 8 | implementation fileTree(dir: 'libs', include: ['*.jar']) 9 | } 10 | 11 | sourceCompatibility = '1.8' 12 | targetCompatibility = '1.8' 13 | -------------------------------------------------------------------------------- /server/src/main/java/nju/androidchat/server/handlers/MessageHandler.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.server.handlers; 2 | 3 | import nju.androidchat.server.ConnectionHandler; 4 | import nju.androidchat.shared.message.Message; 5 | 6 | public interface MessageHandler { 7 | void handle(T message, ConnectionHandler connectionHandler); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvc1/Mvc1BackupController.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvc1; 2 | 3 | import lombok.AllArgsConstructor; 4 | 5 | @AllArgsConstructor 6 | public class Mvc1BackupController { 7 | 8 | public Mvc1BackupModel model; 9 | 10 | public void backup() { 11 | model.backup(); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /server/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | 3 | dependencies { 4 | compileOnly 'org.projectlombok:lombok:1.18.8' 5 | annotationProcessor 'org.projectlombok:lombok:1.18.8' 6 | 7 | implementation project(":shared") 8 | implementation fileTree(dir: 'libs', include: ['*.jar']) 9 | } 10 | 11 | sourceCompatibility = '1.8' 12 | targetCompatibility = '1.8' 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_send.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /server/src/main/java/nju/androidchat/server/ConnectionHandler.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.server; 2 | 3 | import nju.androidchat.shared.message.Message; 4 | 5 | public interface ConnectionHandler { 6 | void sendToAllOtherClients(Message message); 7 | 8 | void setTerminate(boolean terminate); 9 | 10 | String getUsername(); 11 | 12 | void log(String content); 13 | } 14 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/RecallMessage.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | 3 | import java.util.UUID; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | import lombok.ToString; 8 | 9 | @ToString 10 | @AllArgsConstructor 11 | public class RecallMessage extends Message { 12 | @Getter 13 | private UUID messageId; 14 | } 15 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/ErrorMessage.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.ToString; 6 | 7 | /** 8 | * 服务器到客户端:发生错误 9 | */ 10 | @ToString 11 | @AllArgsConstructor 12 | public class ErrorMessage extends Message { 13 | @Getter 14 | private String errorMessage; 15 | } 16 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Start_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 8dp 6 | 176dp 7 | 16dp 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Server.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvvm2/viewmodel/UiOperator.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvvm2.viewmodel; 2 | 3 | 4 | import nju.androidchat.client.mvvm2.model.ClientMessageObservable; 5 | 6 | public interface UiOperator{ 7 | void runOnUiThread(Runnable action); 8 | void scrollListToBottom(); 9 | void showRecallUi(ClientMessageObservable messageObservable, RecallHandler recallHandler); 10 | } 11 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/RecallRequestMessage.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | 3 | import java.util.UUID; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.ToString; 9 | 10 | @AllArgsConstructor 11 | @ToString 12 | public class RecallRequestMessage extends Message { 13 | @Getter 14 | private UUID messageId; 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_slideshow.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_gallery.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/test/java/nju/androidchat/client/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_manage.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/header_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /作业提交说明.md: -------------------------------------------------------------------------------- 1 | # 作业提交说明 2 | 3 | 请所有同学遵照以下流程做本作业: 4 | 5 | - fork本项目,并保持你的项目是public的 6 | - 在**作业信息.txt**里写上自己的学号和作业选项(作业选项用1、2或者3表示) 7 | - 使用Android Studio最新版(3.4.1)打开本项目 8 | - **复制**一遍作业基础代码所在的包,并改名为**hw{作业编号1,2,3}**,在新包里完成工作 9 | - 例如:如果你想做第一个作业,就复制一遍包`mvp0`到`nju.androidchat.client`包里,并新包改名为`hw1`。 10 | - 在提交前,确保将`assets/config.properties`中的`chat_activity`改为你的作业的主Activity 11 | 12 | # 注意 13 | 14 | - 你的包里的Activity是否改名可选,建议改名(即改成例如`Hw1TalkActivity`) 15 | - 提交到自己的仓库里即可,不要给原repo提交PR 16 | - 请确保使用Android 9.0的模拟器能够运行你的项目 17 | 18 | # 作业澄清 19 | 20 | - 作业1:URL为网络地址,不需要处理本地地址 -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/ClientSendMessage.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | import lombok.AllArgsConstructor; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | import lombok.ToString; 10 | 11 | 12 | /** 13 | * 客户端到服务器:发送信息 14 | */ 15 | @ToString 16 | @AllArgsConstructor 17 | public class ClientSendMessage extends Message { 18 | 19 | @Getter 20 | private UUID messageId; 21 | 22 | @Getter 23 | private LocalDateTime time; 24 | 25 | @Getter 26 | private String message; 27 | } 28 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/LoginResponseMessage.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | import lombok.AllArgsConstructor; 3 | import lombok.Getter; 4 | import lombok.ToString; 5 | 6 | /** 7 | * 服务器到客户端:登录响应 8 | * 登录写法:并不是像HTTP一样一个request一个response! 9 | * 客户端发送流和响应流是分开的! 10 | * 所以在登录按钮按下前,就初始化客户端的SocketClient建立Socket连接 11 | * 然后在这个连接上调用writeToServer,发出LoginRequestMessage信息 12 | * 然后当SocketClient接受到LoginResponseMessage信息时说明登录成功 13 | */ 14 | @ToString 15 | @AllArgsConstructor 16 | public class LoginResponseMessage extends Message { 17 | @Getter 18 | private String loggedInUsername; 19 | } 20 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/ServerSendMessage.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | import lombok.AllArgsConstructor; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | import lombok.ToString; 10 | 11 | @ToString 12 | @AllArgsConstructor 13 | public class ServerSendMessage extends Message { 14 | @Getter 15 | private UUID messageId; 16 | 17 | @Getter 18 | private LocalDateTime time; 19 | 20 | @Getter 21 | private String senderUsername; 22 | 23 | @Getter 24 | private String message; 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_camera.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /shared/src/main/java/nju/androidchat/shared/message/LoginRequestMessage.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.shared.message; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | 8 | /** 9 | * 客户端到服务器:登录请求 10 | * 登录写法:并不是像HTTP一样一个request一个response! 11 | * 客户端发送流和响应流是分开的! 12 | * 所以在登录按钮按下前,就初始化客户端的SocketClient建立Socket连接 13 | * 然后在这个连接上调用writeToServer,发出LoginRequestMessage信息 14 | * 然后当SocketClient接受到LoginResponseMessage信息时说明登录成功 15 | * 16 | */ 17 | @ToString 18 | @AllArgsConstructor 19 | public class LoginRequestMessage extends Message { 20 | @Getter 21 | private String username; 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvc1/Mvc1TalkController.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvc1; 2 | 3 | import android.os.AsyncTask; 4 | 5 | import lombok.AllArgsConstructor; 6 | import nju.androidchat.client.Utils; 7 | 8 | @AllArgsConstructor 9 | public class Mvc1TalkController { 10 | 11 | private Mvc1TalkModel model; 12 | private Mvc1TalkActivity activity; 13 | 14 | // Controller将View传来的请求转发给Model进行处理 15 | public void sendInformation(String message) { 16 | model.sendInformation(message); 17 | } 18 | 19 | 20 | public void jumpBackToHome() { 21 | AsyncTask.execute(() -> { 22 | model.disconnect(); 23 | }); 24 | 25 | Utils.jumpToHome(activity); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_share.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvc0/Mvc0TalkController.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvc0; 2 | 3 | import android.os.AsyncTask; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.experimental.ExtensionMethod; 7 | import nju.androidchat.client.Utils; 8 | 9 | @AllArgsConstructor 10 | public class Mvc0TalkController { 11 | 12 | private Mvc0TalkModel model; 13 | private Mvc0TalkActivity activity; 14 | 15 | // Controller将View传来的请求转发给Model进行处理 16 | public void sendInformation(String message) { 17 | model.sendInformation(message); 18 | } 19 | 20 | 21 | public void jumpBackToHome() { 22 | AsyncTask.execute(() -> { 23 | model.disconnect(); 24 | }); 25 | 26 | Utils.jumpToHome(activity); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvp0/Mvp0Contract.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvp0; 2 | 3 | import java.util.List; 4 | 5 | import nju.androidchat.client.ClientMessage; 6 | 7 | public interface Mvp0Contract { 8 | interface View extends BaseView { 9 | void showMessageList(List messages); 10 | } 11 | 12 | interface Presenter extends BasePresenter { 13 | void sendMessage(String content); 14 | 15 | void receiveMessage(ClientMessage content); 16 | 17 | String getUsername(); 18 | 19 | //撤回消息mvp0不实现 20 | void recallMessage(int index0); 21 | } 22 | 23 | interface Model { 24 | ClientMessage sendInformation(String message); 25 | 26 | String getUsername(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/nju/androidchat/client/mvp1/Mvp1BackupModel.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.client.mvp1; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import lombok.extern.java.Log; 8 | 9 | @Log 10 | public class Mvp1BackupModel implements Mvp1Contract.BackupModel { 11 | 12 | @Setter 13 | private Mvp1Contract.BackupPresenter iMvp1BackupPresenter; 14 | 15 | @Getter 16 | private LocalDateTime lastUpdated = null; 17 | 18 | @Override 19 | public void backup() { 20 | // Simulate a HTTP request 21 | try { 22 | Thread.sleep(3000); 23 | lastUpdated = LocalDateTime.now(); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /server/src/main/java/nju/androidchat/server/handlers/DisconnectMessageHandler.java: -------------------------------------------------------------------------------- 1 | package nju.androidchat.server.handlers; 2 | 3 | import lombok.extern.java.Log; 4 | import nju.androidchat.server.ChatServer; 5 | import nju.androidchat.server.ConnectionHandler; 6 | import nju.androidchat.shared.message.DisconnectMessage; 7 | 8 | @Log 9 | public class DisconnectMessageHandler implements MessageHandler { 10 | @Override 11 | public void handle(DisconnectMessage message, ConnectionHandler connectionHandler) { 12 | connectionHandler.log("Disconnect request received. Terminating connection of " + connectionHandler.getUsername()); 13 | connectionHandler.setTerminate(true); 14 | ChatServer.connectionMap.remove(connectionHandler.getUsername()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 |