登录功能的操作逻辑步骤如下:可以分为五个步骤来实现。
1、进入页面先判断用户是否已经登录

private void isLogin() {
        //查看本地是否有用户的登录信息
        SharedPreferences sp = this.getActivity().getSharedPreferences("user_info", Context.MODE_PRIVATE);
        String name = sp.getString("name", "");
        if (TextUtils.isEmpty(name)) {
            //本地没有保存过用户信息,给出提示:登录
            doLogin();
        } else {
            //已经登录过,直接加载用户的信息并显示
            doUser();
        }
    }

2、没有登录过,则提示用户登录,点击后跳转到登录页面

//提示用户登录
    private void doLogin() {
        new AlertDialog.Builder(this.getActivity())
                .setTitle("提示")
                .setMessage("您还没有登录哦!么么~")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
//                UIUtils.toast("进入登录界面",false);
                        ((BaseActivity) MeFragment.this.getActivity()).goToActivity(LoginActivity.class, null);
                    }
                })
                .setCancelable(false)
                .show();
    }

3、在登录页面中做登录操作,登录成功后保存相应的用户信息到本地

//保存用户信息
    public void saveUser(User user){
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("name",user.getName());
        editor.putString("imageurl",user.getImageurl());
        editor.putBoolean("iscredit",user.isCredit());
        editor.putString("phone",user.getPhone());
        editor.commit();//必须提交,否则保存不成功
    }

4、用户已经登录过了,则加载并显示相应的信息

//加载用户信息并显示
    private void doUser() {
        //1.读取本地保存的用户信息
        User user = ((BaseActivity) this.getActivity()).readUser();
        //2.获取对象信息,并设置给相应的视图显示
        tvMeName.setText(user.getName());
        //判断本地是否已经保存头像的图片,如果有,则不执行联网操作
        boolean isExist = readImage();
        if (isExist){
            return;
        }
        //使用Picasso联网获取图片
        Picasso.with(this.getActivity()).load(user.getImageurl()).transform(new Transformation() {
            @Override
            public Bitmap transform(Bitmap source) {//下载以后的内存中的bitmap对象
                //压缩处理
                Bitmap bitmap = BitmapUtils.zoom(source, UIUtils.dp2px(62), UIUtils.dp2px(62));
                //图形处理
                bitmap = BitmapUtils.circleBitmap(bitmap);
                //回收bitmap对象
                source.recycle();
                return bitmap;
            }

            @Override
            public String key() {
                return "";
            }
        }).into(ivMeIcon);
    }

5、退出登录,需要清除本地保存的用户信息

public void logout(View view){//"退出登录"button的回调方法
        //1、将保存在sp中的数据删除
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        sp.edit().clear().commit();//清除数据必须要提交:提交以后,文件仍存在,只是文件中的数据被清除了
        //2、将本地保存的图片的file删除
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//判断sd卡是否挂载
            //路径1:storage/sdcard/Android/data/包名/files
            filesDir = this.getExternalFilesDir("");
        } else {//手机内部存储
            //路径:data/data/包名/files
            filesDir = this.getFilesDir();
        }
        File file = new File(filesDir, "icon.png");
        if (file.exists()){
            file.delete();//删除存储中的文件
        }
        //3、销毁所有的Activity
        this.removeAll();
        //4、重新进入首页面
        goToActivity(MainActivity.class,null);
    }

登录返回的信息实体类User.class

public class User {
    private int id;// 编号
    private String name;// 姓名
    private String password;// 密码
    private String phone;// 手机号
    private String imageurl;// 头像地址
    private boolean iscredit;// 是否公安部认证

    public User() {
        super();
    }

    public User(int id, String name, String password, String phone) {
        super();
        this.id = id;
        this.name = name;
        this.password = password;
        this.phone = phone;
    }

    public User(int id, String name, String password, String phone,
            String imageurl) {
        super();
        this.id = id;
        this.name = name;
        this.password = password;
        this.phone = phone;
        this.imageurl = imageurl;
    }

    public User(int id, String name, String password, String phone,
            String imageurl, boolean iscredit) {
        super();
        this.id = id;
        this.name = name;
        this.password = password;
        this.phone = phone;
        this.imageurl = imageurl;
        this.iscredit = iscredit;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getImageurl() {
        return imageurl;
    }

    public void setImageurl(String imageurl) {
        this.imageurl = imageurl;
    }

    public boolean isCredit() {
        return iscredit;
    }

    public void setCredit(boolean iscredit) {
        this.iscredit = iscredit;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password
                + ", phone=" + phone + ", imageurl=" + imageurl + ", iscredit="
                + iscredit + "]";
    }

}

登录的时候,后台返回的信息,我们需要把常用的用户信息保存到本地。
保存代码方法如下:

//保存用户信息
    public void saveUser(User user){
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("name",user.getName());
        editor.putString("imageurl",user.getImageurl());
        editor.putBoolean("iscredit",user.isCredit());
        editor.putString("phone",user.getPhone());
        editor.commit();//必须提交,否则保存不成功
    }

读取用户信息方法如下:

//读取用户信息
    public User readUser(){
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        User user = new User();
        user.setName(sp.getString("name",""));
        user.setImageurl(sp.getString("imageurl",""));
        user.setPhone(sp.getString("phone",""));
        user.setCredit(sp.getBoolean("iscredit",false));
        return user;
    }

退出登录的时候,需要把用户信息清除。代码方法如下:

public void logout(View view){//"退出登录"button的回调方法
        //1、将保存在sp中的数据删除
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        sp.edit().clear().commit();//清除数据必须要提交:提交以后,文件仍存在,只是文件中的数据被清除了
        //2、将本地保存的图片的file删除
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//判断sd卡是否挂载
            //路径1:storage/sdcard/Android/data/包名/files
            filesDir = this.getExternalFilesDir("");
        } else {//手机内部存储
            //路径:data/data/包名/files
            filesDir = this.getFilesDir();
        }
        File file = new File(filesDir, "icon.png");
        if (file.exists()){
            file.delete();//删除存储中的文件
        }
        //3、销毁所有的Activity
        this.removeAll();
        //4、重新进入首页面
        goToActivity(MainActivity.class,null);
    }

将bitmap图片保存到本地的操作

//将bitmap保存到本地的操作
    /**
     * 数据的存储。(5种)
     * Bimap:内存层面的图片对象。
     *
     * 存储--->内存:
     *      BitmapFactory.decodeFile(String filePath);
     *      BitmapFactory.decodeStream(InputStream is);
     * 内存--->存储:
     *      bitmap.compress(Bitmap.CompressFormat.PNG,100,OutputStream os);
     */
    private void saveImage(Bitmap bitmap) {
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判断sd卡是否挂载
            //路径1:storage/sdcard/Android/data/包名/files
            filesDir = this.getExternalFilesDir("");
        }else {//手机内部存储
            //路径:data/data/包名/files
            filesDir = this.getFilesDir();
        }
        FileOutputStream fos = null;
        try {
            File file = new File(filesDir,"icon.png");
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG,100,fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

读取本地保存的图片,并设置到相应的ImageView控件

//读取本地保存的头像图片
    private void readImage(ImageView img) {
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//判断sd卡是否挂载
            //路径1:storage/sdcard/Android/data/包名/files
            filesDir = this.getExternalFilesDir("");
        } else {//手机内部存储
            //路径:data/data/包名/files
            filesDir = this.getFilesDir();
        }
        File file = new File(filesDir, "icon.png");
        if (file.exists()){
            //存储-->内存
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
            img.setImageBitmap(bitmap);
        }
    }

Activity的管理器类代码如下:

import android.app.Activity;

import java.util.Stack;

/**
 * 作者: willkong on 2017/10/31.
 * 作用:统一应用程序中所有的Activity的栈管理(单例)
 *      涉及到activity的添加、删除指定、删除当前、删除所有、返回栈大小的方法
 */
public class ActivityManager {
    //单例模式:饿汉式
    private ActivityManager(){

    }
    private static ActivityManager activityManager = new ActivityManager();

    public static ActivityManager getInstance(){
        return activityManager;
    }

    //提供栈的对象
    private Stack<Activity> activityStack = new Stack<>();

    //activity的添加
    public void add(Activity activity){
        if(activity != null){
            activityStack.add(activity);
        }
    }

    //插曲:[12,3,44,6,332,65,-56,1]
    //删除指定的activity
    public void remove(Activity activity){
        if(activity != null){
//            for(int i = 0; i < activityStack.size(); i++) {
//                Activity currentActivity = activityStack.get(i);
//                if(currentActivity.getClass().equals(activity.getClass())){
//                    currentActivity.finish();//销毁当前的activity
//                    activityStack.remove(i);//从栈空间移除
//                }
//            }

            for(int i = activityStack.size() - 1;i >= 0;i--){
                Activity currentActivity = activityStack.get(i);
                if(currentActivity.getClass().equals(activity.getClass())){
                    currentActivity.finish();//销毁当前的activity
                    activityStack.remove(i);//从栈空间移除
                }
            }
        }
    }

    //删除当前的activity
    public void removeCurrent(){
        //方式一:
//        Activity activity = activityStack.get(activityStack.size() - 1);
//        activity.finish();
//        activityStack.remove(activityStack.size() - 1);

        //方式二:
        Activity activity = activityStack.lastElement();
        activity.finish();
        activityStack.remove(activity);
    }

    //删除所有的activity
    public void removeAll(){
        for (int i = activityStack.size() - 1;i >= 0;i--){
            Activity activity = activityStack.get(i);
            activity.finish();
            activityStack.remove(activity);
        }
    }

    //返回栈大小
    public int size(){
        return activityStack.size();
    }
}

用法是在基类BaseActivity中进行初始化,并编写操作方法。
在BaseActivity的onCreate方法中初始化管理器

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //将当前的Activity添加到ActivityManager中
        ActivityManager.getInstance().add(this);
    }
//启动新的Activity
    public void goToActivity(Class Activity,Bundle bundle){
        Intent intent = new Intent(this,Activity);
        if (bundle!=null&&bundle.size()!=0){
            intent.putExtra("data",bundle);
        }
        startActivity(intent);
    }

    //销毁当前的Activity
    public void removeCurrentActivity(){
        ActivityManager.getInstance().removeCurrent();
    }

    //销毁所有的Activity
    public void removeAll(){
        ActivityManager.getInstance().removeAll();
    }

图像处理工具类BitmapUtils.class

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;

/**
 * 作者: willkong on 2017/11/21.
 * 作用:图像处理工具类
 */
public class BitmapUtils {
    public static Bitmap circleBitmap(Bitmap source) {

        int width = source.getWidth();
        Bitmap bitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawCircle(width / 2, width / 2, width / 2, paint);

        //设置图片相交情况下的处理方式
        //setXfermode:设置当绘制的图像出现相交情况时候的处理方式的,它包含的常用模式有:
        //PorterDuff.Mode.SRC_IN 取两层图像交集部分,只显示上层图像
        //PorterDuff.Mode.DST_IN 取两层图像交集部分,只显示下层图像
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

        canvas.drawBitmap(source, 0, 0, paint);

        return bitmap;
    }

    //实现图片的压缩处理
    public static Bitmap zoom(Bitmap source,float w,float h){
        Matrix matrix = new Matrix();
        //图片的压缩处理
        matrix.postScale(w / source.getWidth(),h / source.getHeight());

        Bitmap bitmap = Bitmap.createBitmap(source,0,0,source.getWidth(),source.getHeight(),matrix,true);
        return bitmap;
    }
}