开头
现在要说最火的Android软件无非是微博、微信和抖音,但这三个软件是相互独立的,能不能自己实现一个androidApp同时。答案是可以的,而且个人实现并不非常困难。这里我个人就实现了一个三者主要功能合一的app。话不多说先上一段演示视频。
如果觉得不错的同学,想体验该软件的,可以去蒲公英https://www.pgyer.com/xK5X进行下载尝试。如果遇到问题欢迎询问,如果有愿意商业合作开发的也可以商谈。
好了下面该说说怎么写一个这样的APP了。
一、任务分解
既然是一个微博、微信、抖音三合一的app,那肯定包括这三家当家功能。短视频播放上传、博客的上传发布和浏览、即时通讯、朋友圈。下面是具体的功能划分。
当然这仅仅是初期的功能、例如删除修改微博、好友申请、好友删除、关注等功能则需要程序开发人员自己设计好软件设计说明书了。不得不说还是很考验架构水平的。如果想实现好整个系统,则后端前端都必不可少。
二、具体功能分析
这里以登录功能为例简单谈谈怎么设计在公司合作开发功能。登录功能要用到的就是账号验证功能、账号注册功能、手机验证码验证功能。这里先设计这一功能的用户这一个数据表的属性设计。
因为有即使通讯,在制作之前要选择好即时通讯的技术结构,是买第三方即时通讯服务(比如环信),还是自己研发一套即时通讯体系,这块就自由发挥了。用户数据不光要在服务端数据库进行保存、Android本地数据也要保存一份,用来自动登录,如果没有的话用户每次都要从登录界面开始是十分麻烦的。
我这里使用的是环信的社区版,用户数据用greenDao进行本地数据库保存,因为环信有自己的登录验证API,我们只需要读取数据库里的用户环信ID进行登录,如果登录不成功则跳转到登录界面。
private void loginHuanxin() {
String userName;
String password;
if(UserTableDao.getInstance().loadAll().size() > 0){
userName = UserTableDao.getInstance().loadAll().get(0).getEasemobName();
password = UserTableDao.getInstance().loadAll().get(0).getEasemobPassword();
}else{
worlds.setVisibility(View.INVISIBLE);
loginButton.setVisibility(View.VISIBLE);
registerButton.setVisibility(View.VISIBLE);
return;
}
EMClient.getInstance().login(userName,password,new EMCallBack() {//回调
@Override
public void onSuccess() {
EMClient.getInstance().groupManager().loadAllGroups();
EMClient.getInstance().chatManager().loadAllConversations();
//跳转到主页
Intent intent = new Intent(InitialActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
@Override
public void onProgress(int progress, String status) {
}
@Override
public void onError(int code, String message) {
Log.d("main", "登录聊天服务器失败!");
finish();
}
});
}
如果用户第一次使用,则需要通用手机号进行注册,具体逻辑是这样的。
服务端接受到验证码发送请求后用redis数据库进行时间有效性存储,当接受到验证码验证请求时,请求体中的验证码和redis保存的验证码进行比对并返回结果。
public class SendVerifyCodeActivity extends AppCompatActivity implements SendVerifyCodeContract.View {
private ImageView backButton;//后退按钮
private EditText phoneNumEt;//手机号输入框
private Button nextButton;//下一步按钮
private SendVerifyCodeModel sendVerifyCodeModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_verify_code);
initData();
initView();
initListener();
}
private void initData() {
sendVerifyCodeModel = new SendVerifyCodeModel(this);
}
private void initListener() {
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String phoneNum = phoneNumEt.getText().toString();
sendVerifyCodeModel.SendVerifyCode(new SendVerifyCodeRequest(phoneNum));
}
});
phoneNumEt.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(StringUtils.isEmpty(phoneNumEt.getText().toString())){
nextButton.setActivated(false);
}else{
nextButton.setActivated(true);
}
}
});
}
private void initView(){
backButton = findViewById(R.id.btn_back);
phoneNumEt = findViewById(R.id.et_phone_num);
nextButton = findViewById(R.id.bt_next);
nextButton.setActivated(false);
}
@Override
public void SendVerifyCodeFinish(MessageBody messageBody) {
if(messageBody.getCode().equals("0")){
//发送验证码成功,跳转
Intent intent = new Intent(SendVerifyCodeActivity.this, InputCodeActivity.class);
intent.putExtra("phoneNum",phoneNumEt.getText().toString());
intent.putExtra("type",0);
startActivity(intent);
finish();
}else {
Toast.makeText(this,messageBody.getMsg(),Toast.LENGTH_SHORT).show();
}
}
}
public class SendVerifyCodeModel implements SendVerifyCodeContract.Model {
private SendVerifyCodeContract.View view;
public SendVerifyCodeModel(SendVerifyCodeContract.View view) {
this.view = view;
}
@Override
public void SendVerifyCode(SendVerifyCodeRequest request) {
Retrofit2Utils.getClient().create(GetAsk.class).sendVerificationCode(request)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<MessageBody>() {
Disposable disposable;
@Override
public void onSubscribe(Disposable d) {
disposable = d;
}
@Override
public void onNext(MessageBody messageBody) {
view.SendVerifyCodeFinish(messageBody);
}
@Override
public void onError(Throwable e) {
if(disposable != null && !disposable.isDisposed()){
disposable.dispose();
}
}
@Override
public void onComplete() {
}
});
}
}
当用户注册完毕后尽可以进入主页了,关于主页的功能分析我们下次继续。