Android Notification通知简单封装(适配8.0)

image

一、简介
二、效果预览
三、实现步骤
四、源码分析
五、Demo地址
六、内容推荐

一、简介

这是一篇介绍简单实现通知notification的文章,并不会太深入。只是让大家使用通知的时候,能够节省开发时间。详细使用步骤或者方法可以到官网查看API文档https://developer.android.google.cn/reference/android/support/v4/app/NotificationCompat.Builder。简单的给大家推荐一个工具类,后续若有更好的发现会及时更新。

二、效果预览

image

​三、实现步骤

1、工具类

import android.annotation.TargetApi;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.text.TextUtils;
import android.widget.RemoteViews;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import blcs.lwb.lwbtool.R;

import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static android.content.Context.NOTIFICATION_SERVICE;
import static android.support.v4.app.NotificationCompat.PRIORITY_DEFAULT;

/**
 * TODO 通知栏工具 BLCS
 * https://developer.android.google.cn/reference/android/support/v4/app/NotificationCompat.Builder
 */
public class LinNotify {

    public static final int RequestCode = 1;
    public static final String NEW_MESSAGE = "chat";
    public static final String NEW_GROUP = "chat_group";
    public static final String OTHER_MESSAGE = "other";
    public static final String Ticker = "您有一条新的消息";
    public static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
    public static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
    public static int notifyId = 0;

    /**
     * TODO 适配 Android8.0  创建通知渠道
     * tips:可以写在MainActivity中,也可以写在Application中,实际上可以写在程序的任何位置,
     * 只需要保证在通知弹出之前调用就可以了。并且创建通知渠道的代码只在第一次执行的时候才会创建,
     * 以后每次执行创建代码系统会检测到该通知渠道已经存在了,因此不会重复创建,也并不会影响任何效率。
     */
    public static void setNotificationChannel(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = NEW_MESSAGE;
            String channelName = "新消息通知";
            createNotificationChannel(context, channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
            channelId = OTHER_MESSAGE;
            channelName = "其他通知";
            createNotificationChannel(context, channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
        }
    }

    /**
     * 创建配置通知渠道
     * @param channelId   渠道id
     * @param channelName 渠道nanme
     * @param importance  优先级
     */
    @TargetApi(Build.VERSION_CODES.O)
    private static void createNotificationChannel(Context context, String channelId, String channelName, int importance) {
//        createNotifycationGroup(context,channelId,channelName);
        NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
        channel.setShowBadge(false);//禁止该渠道使用角标
//        channel.setGroup(channelId); //设置渠道组id
        // 配置通知渠道的属性
//        channel .setDescription("渠道的描述");
        // 设置通知出现时的闪灯(如果 android 设备支持的话)
        channel.enableLights(true);
        // 设置通知出现时的震动(如果 android 设备支持的话)
        channel.enableVibration(false);
        //如上设置使手机:静止1秒,震动2秒,静止1秒,震动3秒
//        channel.setVibrationPattern(new long[]{1000, 2000, 1000,3000});
        channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);//设置锁屏是否显示通知
        channel.setLightColor(Color.BLUE);
        channel.setBypassDnd(true);//设置是否可以绕过请勿打扰模式
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(
                NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(channel);
    }

    /**
     * 创建渠道组(若通知渠道比较多的情况下可以划分渠道组)
     * @param groupId
     * @param groupName
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static void createNotifycationGroup(Context context,String groupId, String groupName) {
        NotificationChannelGroup group = new NotificationChannelGroup(groupId, groupName);
        NotificationManager notificationManager = (NotificationManager)context.getSystemService(
                NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannelGroup(group);
    }

    /**
     * TODO: 发送通知(刷新前面的通知)
     *
     * @param context
     * @param contentTitle 标题
     * @param contentText  内容
     */
    public static void show(Context context, String contentTitle, String contentText, Class<?> cls) {
        show(context, contentTitle, contentText,null, 0, NEW_MESSAGE, cls);
    }

    /**
     * TODO: 发送自定义通知(刷新前面的通知)
     *
     * @param context
     * @param contentTitle 标题
     * @param contentText  内容
     */
    public static void show(Context context, String contentTitle, String contentText,RemoteViews views ,Class<?> cls) {
        show(context, contentTitle, contentText, views,0, NEW_MESSAGE, cls);
    }

    /**
     * 发送通知(刷新前面的通知,指定通知渠道)
     *
     * @param contentTitle 标题
     * @param contentText  内容
     * @param channelId    渠道id
     */
    public static void show(Context context, String contentTitle, String contentText, String channelId, Class<?> cls) {
        show(context, contentTitle, contentText,null, 0, channelId, cls);
    }

    /**
     * 发送自定义通知(刷新前面的通知,指定通知渠道)
     *
     * @param contentTitle 标题
     * @param contentText  内容
     * @param channelId    渠道id
     */
    public static void show(Context context, String contentTitle, String contentText,RemoteViews views, String channelId, Class<?> cls) {
        show(context, contentTitle, contentText,views, 0, channelId, cls);
    }

    /**
     * 发送多条通知(默认通知渠道)
     *
     * @param contentTitle 标题
     * @param contentText  内容
     */
    public static void showMuch(Context context, String contentTitle, String contentText, Class<?> cls) {
        show(context, contentTitle, contentText,null, ++notifyId, NEW_MESSAGE, cls);
    }

    /**
     * 发送多条自定义通知(默认通知渠道)
     *
     * @param contentTitle 标题
     * @param contentText  内容
     */
    public static void showMuch(Context context, String contentTitle, String contentText,RemoteViews views, Class<?> cls) {
        show(context, contentTitle, contentText,views, ++notifyId, NEW_MESSAGE, cls);
    }

    /**
     * 发送多条通知(指定通知渠道)
     *
     * @param contentTitle 标题
     * @param contentText  内容
     * @param channelId    渠道id
     */
    public static void showMuch(Context context, String contentTitle, String contentText, String channelId, Class<?> cls) {
        show(context, contentTitle, contentText,null, ++notifyId, channelId, cls);
    }

    /**
     * 发送多条自定义通知(指定通知渠道)
     *
     * @param contentTitle 标题
     * @param contentText  内容
     * @param channelId    渠道id
     */
    public static void showMuch(Context context, String contentTitle, String contentText, String channelId,RemoteViews views, Class<?> cls) {
        show(context, contentTitle, contentText,views, ++notifyId, channelId, cls);
    }

    /**
     * 发送通知(设置默认:大图标/小图标/小标题/副标题/优先级/首次弹出文本)
     *
     * @param contentTitle 标题
     * @param contentText  内容
     * @param notifyId     通知栏id
     * @param channelId    设置渠道id
     * @param cls          意图类
     */
    public static void show(Context context, String contentTitle, String contentText, RemoteViews views,int notifyId, String channelId, Class<?> cls) {
        show(context, 0, 0, contentTitle, null, contentText, PRIORITY_DEFAULT, null,views ,notifyId, channelId, cls);
    }

    /**
     * 发送通知
     *
     * @param largeIcon    大图标
     * @param smallIcon    小图标
     * @param contentTitle 标题
     * @param subText      小标题/副标题
     * @param contentText  内容
     * @param priority     优先级
     * @param ticker       通知首次弹出时,状态栏上显示的文本
     * @param notifyId     定义是否显示多条通知栏
     * @param cls          意图类
     */
    public static void show(Context context, int largeIcon,
                            int smallIcon, String contentTitle,
                            String subText, String contentText,
                            int priority, String ticker, RemoteViews view,
                            int notifyId, String channelId, Class<?> cls) {
        //flags
        // FLAG_ONE_SHOT:表示此PendingIntent只能使用一次的标志
        // FLAG_IMMUTABLE:指示创建的PendingIntent应该是不可变的标志
        // FLAG_NO_CREATE : 指示如果描述的PendingIntent尚不存在,则只返回null而不是创建它。
        // FLAG_CANCEL_CURRENT :指示如果所描述的PendingIntent已存在,则应在生成新的PendingIntent,取消之前PendingIntent
        // FLAG_UPDATE_CURRENT : 指示如果所描述的PendingIntent已存在,则保留它,但将其额外数据替换为此新Intent中的内容
        PendingIntent pendingIntent = null;
        //添加隐示意图
        if (cls != null) {
            Intent intent = new Intent(context, cls);
            pendingIntent = PendingIntent.getActivity(context, RequestCode, intent, FLAG_UPDATE_CURRENT);
        }
        //获取通知服务管理器
        NotificationManager manager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
        //判断应用通知是否打开
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (!openNotificationChannel(context, manager, channelId)) return;
        }

        //创建 NEW_MESSAGE 渠道通知栏  在API级别26.1.0中推荐使用此构造函数 Builder(context, 渠道名)
        NotificationCompat.Builder builder = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? new NotificationCompat.Builder(context, channelId) : new NotificationCompat.Builder(context);
        builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), largeIcon == 0 ? R.mipmap.ic_launcher : largeIcon)) //设置自动收报机和通知中显示的大图标。
                .setSmallIcon(smallIcon == 0 ? R.mipmap.ic_launcher : smallIcon) // 小图标
                .setContentText(TextUtils.isEmpty(contentText)? null : contentText) // 内容
                .setContentTitle(TextUtils.isEmpty(contentTitle) ? null : contentTitle) // 标题
                .setSubText(TextUtils.isEmpty(subText) ? null : subText) // APP名称的副标题
                .setPriority(priority) //设置优先级 PRIORITY_DEFAULT
                .setTicker(TextUtils.isEmpty(ticker) ? Ticker : ticker) // 设置通知首次弹出时,状态栏上显示的文本
                .setContent(view)
                .setWhen(System.currentTimeMillis()) // 设置通知发送的时间戳
                .setShowWhen(true)//设置是否显示时间戳
                .setAutoCancel(true)// 点击通知后通知在通知栏上消失
                .setDefaults(Notification.PRIORITY_HIGH)// 设置默认的提示音、振动方式、灯光等 使用的默认通知选项
                .setContentIntent(pendingIntent) // 设置通知的点击事件
                //锁屏状态下显示通知图标及标题 1、VISIBILITY_PUBLIC 在所有锁定屏幕上完整显示此通知/2、VISIBILITY_PRIVATE 隐藏安全锁屏上的敏感或私人信息/3、VISIBILITY_SECRET 不显示任何部分
                .setVisibility(Notification.VISIBILITY_PUBLIC)//部分手机没效果
                .setFullScreenIntent(pendingIntent,true)//悬挂式通知8.0需手动打开
//                .setColorized(true)
//                .setGroupSummary(true)//将此通知设置为一组通知的组摘要
//                .setGroup(NEW_GROUP)//使用组密钥
//                .setDeleteIntent(pendingIntent)//当用户直接从通知面板清除通知时 发送意图
//                .setFullScreenIntent(pendingIntent,true)
//                .setContentInfo("大文本")//在通知的右侧设置大文本。
//                .setContent(RemoteViews RemoteView)//设置自定义通知栏
//                .setColor(Color.parseColor("#ff0000"))
//                .setLights()//希望设备上的LED闪烁的argb值以及速率
//                .setTimeoutAfter(3000)//指定取消此通知的时间(如果尚未取消)。
        ;

        // 通知栏id
        manager.notify(notifyId, builder.build()); // build()方法需要的最低API为16 ,
    }

    /**
     * 判断应用渠道通知是否打开(适配8.0)
     * @return true 打开
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static Boolean openNotificationChannel(Context context, NotificationManager manager, String channelId) {
        //判断通知是否有打开
        if (!isNotificationEnabled(context)) {
            toNotifySetting(context, null);
            return false;
        }
        //判断渠道通知是否打开
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = manager.getNotificationChannel(channelId);
            if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
                //没打开调往设置界面
                toNotifySetting(context, channel.getId());
                return false;
            }
        }

        return true;
    }

    /**
     * 判断应用通知是否打开
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static boolean isNotificationEnabled(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
            return notificationManagerCompat.areNotificationsEnabled();
        }
        AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        Class appOpsClass = null;
        /* Context.APP_OPS_MANAGER */
        try {
            appOpsClass = Class.forName(AppOpsManager.class.getName());
            Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE,
                    String.class);
            Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);
            int value = (Integer) opPostNotificationValue.get(Integer.class);
            return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, context.getApplicationInfo().uid, context.getPackageName()) == AppOpsManager.MODE_ALLOWED);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 手动打开应用通知
     */
    public static void toNotifySetting(Context context, String channelId) {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //适配 8.0及8.0以上(8.0需要先打开应用通知,再打开渠道通知)
            if(TextUtils.isEmpty(channelId)){
                intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
            }else{
                intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//适配 5.0及5.0以上
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra("app_package", context.getPackageName());
            intent.putExtra("app_uid", context.getApplicationInfo().uid);
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {// 适配 4.4及4.4以上
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.fromParts("package", context.getPackageName(), null));
        } else {
            intent.setAction(Settings.ACTION_SETTINGS);
        }
        context.startActivity(intent);
    }

}

2、工具的使用方法

//通知栏初始化(适配8.0)
LinNotify.setNotificationChannel(context);

//发送同一个通知
LinNotify.show(activity, "通知栏标题", "通知栏内容", null);

//发送自定义通知
RemoteViews mViews = new RemoteViews(activity.getPackageName(), R.layout.custom_notify);
mViews.setTextViewText(R.id.tv_custom_notify,"正在下载");
mViews.setTextViewText(R.id.tv_custom_notify_number,++progress+"0%");
mViews.setProgressBar(R.id.pb_custom_notify,10,progress,false);
LinNotify.show(activity, StringUtils.getString(et_notification_title), StringUtils.getString(etNotificationContent),mViews, null);

总结:在Application中调用工具初始化通知渠道 ,发送通知时调用工具Show方法即可。

四、源码分析

1、创建通知渠道

    /**
     * TODO 适配 Android8.0  创建通知渠道
     * tips:可以写在MainActivity中,也可以写在Application中,实际上可以写在程序的任何位置,
     * 只需要保证在通知弹出之前调用就可以了。并且创建通知渠道的代码只在第一次执行的时候才会创建,
     * 以后每次执行创建代码系统会检测到该通知渠道已经存在了,因此不会重复创建,也并不会影响任何效率。
     */
    public static void setNotificationChannel(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = NEW_MESSAGE;
            String channelName = "新消息通知";
            createNotificationChannel(context, channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
            channelId = OTHER_MESSAGE;
            channelName = "其他通知";
            createNotificationChannel(context, channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
        }
    }

可以在这个方法中添加应用所需的渠道,android 8.0新增的功能

//创建一个渠道
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);

//渠道添加到通知管理当中
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
                NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);

当然也可以划分渠道组

 /**
     * 创建渠道组(若通知渠道比较多的情况下可以划分渠道组)
     * @param groupId
     * @param groupName
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static void createNotifycationGroup(Context context,String groupId, String groupName) {
        NotificationChannelGroup group = new NotificationChannelGroup(groupId, groupName);
        NotificationManager notificationManager = (NotificationManager)context.getSystemService(
                NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannelGroup(group);
    }

经过测试有些机型并不会显示(没效果)。原因未知...作者是个小菜鸟 。知道的读者可以留言分享下。作者在这里先谢过

1

2、发送通知

感觉都不用解释分析了,已经注释的很明显。

 /**
     * 发送通知
     *
     * @param largeIcon    大图标
     * @param smallIcon    小图标
     * @param contentTitle 标题
     * @param subText      小标题/副标题
     * @param contentText  内容
     * @param priority     优先级
     * @param ticker       通知首次弹出时,状态栏上显示的文本
     * @param notifyId     定义是否显示多条通知栏
     * @param cls          意图类
     */
    public static void show(Context context, int largeIcon,
                            int smallIcon, String contentTitle,
                            String subText, String contentText,
                            int priority, String ticker, RemoteViews view,
                            int notifyId, String channelId, Class<?> cls) {
        //flags
        // FLAG_ONE_SHOT:表示此PendingIntent只能使用一次的标志
        // FLAG_IMMUTABLE:指示创建的PendingIntent应该是不可变的标志
        // FLAG_NO_CREATE : 指示如果描述的PendingIntent尚不存在,则只返回null而不是创建它。
        // FLAG_CANCEL_CURRENT :指示如果所描述的PendingIntent已存在,则应在生成新的PendingIntent,取消之前PendingIntent
        // FLAG_UPDATE_CURRENT : 指示如果所描述的PendingIntent已存在,则保留它,但将其额外数据替换为此新Intent中的内容
        PendingIntent pendingIntent = null;
        //添加隐示意图
        if (cls != null) {
            Intent intent = new Intent(context, cls);
            pendingIntent = PendingIntent.getActivity(context, RequestCode, intent, FLAG_UPDATE_CURRENT);
        }
        //获取通知服务管理器
        NotificationManager manager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
        //判断应用通知是否打开
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (!openNotificationChannel(context, manager, channelId)) return;
        }

        //创建 NEW_MESSAGE 渠道通知栏  在API级别26.1.0中推荐使用此构造函数 Builder(context, 渠道名)
        NotificationCompat.Builder builder = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? new NotificationCompat.Builder(context, channelId) : new NotificationCompat.Builder(context);
        builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), largeIcon == 0 ? R.mipmap.ic_launcher : largeIcon)) //设置自动收报机和通知中显示的大图标。
                .setSmallIcon(smallIcon == 0 ? R.mipmap.ic_launcher : smallIcon) // 小图标
                .setContentText(TextUtils.isEmpty(contentText)? null : contentText) // 内容
                .setContentTitle(TextUtils.isEmpty(contentTitle) ? null : contentTitle) // 标题
                .setSubText(TextUtils.isEmpty(subText) ? null : subText) // APP名称的副标题
                .setPriority(priority) //设置优先级 PRIORITY_DEFAULT
                .setTicker(TextUtils.isEmpty(ticker) ? Ticker : ticker) // 设置通知首次弹出时,状态栏上显示的文本
                .setContent(view)
                .setWhen(System.currentTimeMillis()) // 设置通知发送的时间戳
                .setShowWhen(true)//设置是否显示时间戳
                .setAutoCancel(true)// 点击通知后通知在通知栏上消失
                .setDefaults(Notification.PRIORITY_HIGH)// 设置默认的提示音、振动方式、灯光等 使用的默认通知选项
                .setContentIntent(pendingIntent) // 设置通知的点击事件
                //锁屏状态下显示通知图标及标题 1、VISIBILITY_PUBLIC 在所有锁定屏幕上完整显示此通知/2、VISIBILITY_PRIVATE 隐藏安全锁屏上的敏感或私人信息/3、VISIBILITY_SECRET 不显示任何部分
                .setVisibility(Notification.VISIBILITY_PUBLIC)//部分手机没效果
                .setFullScreenIntent(pendingIntent,true)//悬挂式通知8.0需手动打开
//                .setColorized(true)
//                .setGroupSummary(true)//将此通知设置为一组通知的组摘要
//                .setGroup(NEW_GROUP)//使用组密钥
//                .setDeleteIntent(pendingIntent)//当用户直接从通知面板清除通知时 发送意图
//                .setFullScreenIntent(pendingIntent,true)
//                .setContentInfo("大文本")//在通知的右侧设置大文本。
//                .setContent(RemoteViews RemoteView)//设置自定义通知栏
//                .setColor(Color.parseColor("#ff0000"))
//                .setLights()//希望设备上的LED闪烁的argb值以及速率
//                .setTimeoutAfter(3000)//指定取消此通知的时间(如果尚未取消)。
        ;

        // 通知栏id
        manager.notify(notifyId, builder.build()); // build()方法需要的最低API为16 ,
    }

这篇算是一个笔记,内容不多 。但是使用比较频繁。就归类总结了一下。大家浏览一下估计就懂了,所以也不需要啰啰嗦嗦一大堆。


2.jpg

五、Demo地址

源码地址:https://github.com/DayorNight/BLCS

apk下载体验地址:https://www.pgyer.com/BLCS

六、内容推荐

CSDN:《Android Notification通知简单封装(适配8.0)》

《Android 仿RxDialog自定义DialogFragment》
《Android 获取App应用、缓存、数据等大小适配8.0(仿微信存储空间)》
《Android 仿微信多语言切换》
《Android 仿微信全局字体大小调整》
《Android Rxjava+Retrofit网络请求框架封装(一)》

如果你觉得写的不错或者对您有所帮助的话

不妨顶一个【微笑】,别忘了点赞、收藏、加关注哈

看在花了这么多时间整理写成文章分享给大家的份上,记得手下留情哈

您的每个举动都是对我莫大的支持

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容