Android 中的BaseActivity demo

为什么要baseActivity?BaseFragment

1: 最简单的回复,“如果有些东西是一样的,就抽出来写在BaseActivity上”

2: 更重要的是实现代码的结构化化的显示,结构清晰,每一个activity需要做的事情,事先定义好了



1: 所有的activity 都需要预先做好的事情,写在BaseActivity里面:例如:

友盟统计的初始化

activity的生命周期的log的打印

常量的定义


添加到activity 的列表里面,方便退出的时候activity 的退出

activity的切换的动画


2: 所有的activity 都需要去做的事情,定义成抽象的方法,继承BaseActivity的activity 必须要去实现

例如:

    /**
     * findview 相关的
     */
    protected abstract void findView();

    /**
     * 初始化数据
     */
    protected abstract void initData();

    /**
     * 初始化View
     */
    protected abstract void initView();

    /**
     * View的点击事件
     */
    protected abstract void setOnClick();


顺便说一下activity的切换的动画: 

利用Theme自定义Activity间的切换动画 

android Activity setTheme() 更改主题


3: BaseActivity的部分的代码demo:

千万需要记住的就是,一些重要的全局变量,需要在onSaveInstance onRestoreInstance的时候进行保存和恢复,(参考:[已解决]项目中应用来回切换后,就会提示“已停止运行”



package com.example.kodulf.utilsdemo.activity;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;

import com.example.kodulf.utilsdemo.MyApplication;
import com.example.kodulf.utilsdemo.R;
import com.example.kodulf.utilsdemo.utils.AppUtils;
import com.umeng.analytics.MobclickAgent;

/**
 * Created by Kodulf on 2017/5/13.
 */

public abstract class BaseActivity extends AppCompatActivity{
    public static final int UMENG_PHONE_STATE_REQUEST = 998;
    private boolean isDebug;
    private String APP_NAME="Kodulf";
    protected final String ACTIVITY_NAME = this.getClass().getSimpleName();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //添加到列表中, 可能会重复的添加,例如有进行横竖屏的切换,没有关系的添加进去就可以了
        MyApplication.mActivityList.addFirst(this);

        //设置统一的切换的动画
        this.setTheme(R.style.Anim_fade);

        Log.d(APP_NAME, ACTIVITY_NAME +"-->onCreate");
        thirdPartyInitOnCreate();

        //默认的排序也给出
        findView();
        initView();
        initData();
        setOnClick();
    }


    /**
     * 第三方的初始化
     */
    public void thirdPartyInitOnCreate(){
        initUmeng();
    }

    /**
     * 第三方的onPause
     */
    public void thirdPartyOnPause(){
        MobclickAgent.onPause(this);
    }

    /**
     * 第三方的onResume
     */
    public void thirdPartyOnResume(){
        MobclickAgent.onResume(this);
    }


    @Override
    protected void onResume() {
        super.onResume();
        Log.d(APP_NAME, ACTIVITY_NAME +"-->onResume");
        thirdPartyOnResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(APP_NAME, ACTIVITY_NAME +"-->onPause");
        thirdPartyOnPause();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(APP_NAME, ACTIVITY_NAME +"-->onStart");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(APP_NAME, ACTIVITY_NAME +"-->onRestart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(APP_NAME, ACTIVITY_NAME +"-->onStop");
    }

    /**
     * findview 相关的
     */
    protected abstract void findView();

    /**
     * 初始化数据
     */
    protected abstract void initData();

    /**
     * 初始化View
     */
    protected abstract void initView();

    /**
     * View的点击事件
     */
    protected abstract void setOnClick();

    /**
     * 需要在onSaveInstance里面执行的
     * 例如像是一些全局变量,可以在这里保存了,然后再在onRestoreInstance里面执行
     * 如果在内存较少的时候,例如打开了很多的应用,这个时候gc 会将一些切换到后台运行的程序里面的全局变量修改为默认的值,
     * 例如有一个类的全局变量是Cashier ,之前有设置过,但是在上面的那种情况,就会发生再次打开的时候Cashier为null
     * 所以需要在onSaveInstance的时候将它保存,然后在onRestoreInstance的时候在进行加载
     */
    protected void needDoInSaveInstance(){

    };

    /**
     * 需要在onRestoreInstance里面执行的
     */
    protected void needDoInRestoreInstance(){

    };


    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        needDoInSaveInstance();
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        needDoInRestoreInstance();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode){
            case UMENG_PHONE_STATE_REQUEST:

                int permissionId = -1;
                for (int i = 0; i < permissions.length; i++) {
                    String permission = permissions[i];
                    System.out.println("result: permision:"+permission);
                    if(Manifest.permission.READ_PHONE_STATE.equals(permission))
                        permissionId = i;
                }

                if(permissionId>=0&&grantResults.length>=permissionId){
                    int grantResult = grantResults[permissionId];
                    if(grantResult == PackageManager.PERMISSION_GRANTED){
                        //do nothing,or something relate to this permission
                    }else{
                        Toast.makeText(this,"请求权限",Toast.LENGTH_LONG).show();
                        AppUtils.gotoMiuiPermission(this);
                    }
                }


                break;

        }
    }



    /**
     * Umeng相关的
     *
     * http://dev.umeng.com/analytics/android-doc/integration?spm=0.0.0.0.9EfFZE#2_8
     *
     在每个Activity的onResume方法中调用 MobclickAgent.onResume(Context) ,
     onPause方法中调用 MobclickAgent.onPause(Context)

     确保在所有的Activity中都调用 MobclickAgent.onResume() 和MobclickAgent.onPause()方法,这两个调用将不会阻塞应用程序的主线程,也不会影响应用程序的性能。
     注意 如果您的Activity之间有继承或者控制关系请不要同时在父和子Activity中重复添加onPause和onResume方法,否则会造成重复统计,导致启动次数异常增高。(eg.使用TabHost、TabActivity、ActivityGroup时)。
     当应用在后台运行超过30秒(默认)再回到前端,将被认为是两个独立的session(启动),例如用户回到home,或进入其他程序,经过一段时间后再返回之前的应用。可通过接口:MobclickAgent.setSessionContinueMillis(long interval) 来自定义这个间隔(参数单位为毫秒)。
     如果开发者调用Process.kill或者System.exit之类的方法杀死进程,请务必在此之前调用MobclickAgent.onKillProcess(Context context)方法,用来保存统计数据。


     umeng的代码混淆
     如果您的应用使用了混淆, 请添加

     -keepclassmembers class * {
     public <init> (org.json.JSONObject);
     }

     这是由于SDK中的部分代码使用反射来调用构造函数, 如果被混淆掉, 在运行时会提示"NoSuchMethod"错误。 另外,由于SDK需要引用导入工程的资源文件,通过了反射机制得到资源引用文件R.java,但是在开发者通过proguard等混淆/优化工具处理apk时,proguard可能会将R.java删除,如果遇到这个问题,请在proguard配置文件中添加keep命令如:

     -keep public class [您的应用包名].R$*{
     public static final int *;
     }

     把[您的应用包名] 替换成您自己的包名,如com.yourcompany.example。如果您使用5.0.0及以上版本的SDK,请添加如下命令:

     -keepclassmembers enum * {
     public static **[] values();
     public static ** valueOf(java.lang.String);
     }
     **/
    private void initUmeng() {
        //如果是6.0 api23的那么需要reqeust permistion,
        // https://developer.android.com/training/permissions/requesting.html
        if(Build.VERSION.SDK_INT>=23) {
            int i = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
            if (i == PackageManager.PERMISSION_GRANTED) {
                Log.d("kodulf", "有了该权限了");
            } else {
                Log.d("kodulf", "没有该权限");
                //shouldShowRequestPermissionRationale,如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
                //shouldShowRequestPermissionRationale其实就是显不显示那个提示框而已。返回false 就不现实,返回true 就显示
                //默认的也是返回false,还有注:如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false。
                //第一次的时候shouldShowRequestPermissionRationale 会返回false
                //第二次的时候shouldShowRequestPermissionRationale,如果是之前deny了,那么会返回true
                if (shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE)){
                    ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE},UMENG_PHONE_STATE_REQUEST);
                }else{
                    ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE},UMENG_PHONE_STATE_REQUEST);
                }
            }
        }
    }
}



参考:https://www.zhihu.com/question/47045239

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值