Android Alarm自上而下 调试浅析

1.为了创建一个新的Alarm,使用set方法并指定一个Alarm类型、触发时间和在Alarm触发时要调用的Intent。如果你设定的Alarm发生在过去,那么,它将立即触发。

这里有4种Alarm类型。你的选择将决定你在set方法中传递的时间值代表什么,是特定的时间或者是时间流逝:

❑ RTC_WAKEUP

在指定的时刻(设置Alarm的时候),唤醒设备来触发Intent。

❑ RTC

在一个显式的时间触发Intent,但不唤醒设备。

❑ ELAPSED_REALTIME

从设备启动后,如果流逝的时间达到总时间,那么触发Intent,但不唤醒设备。流逝的时间包括设备睡眠的任何时间。注意一点的是,时间流逝的计算点是自从它最后一次启动算起。

❑ ELAPSED_REALTIME_WAKEUP

从设备启动后,达到流逝的总时间后,如果需要将唤醒设备并触发Intent。


2.Alarm 调用流程,alarm的流程实现了从上层应用一直到下面driver的调用流程,下面简单阐述:

点击Clock 应用程序,然后设置新闹钟,会调到  Alarms.java  里面的

[cpp] view plaincopy
  1. public static long setAlarm(Context context, Alarm alarm) {  
  2.     ContentValues values = createContentValues(alarm);  
  3.     ContentResolver resolver = context.getContentResolver();  
  4.     resolver.update(  
  5.             ContentUris.withAppendedId(Alarm.Columns.CONTENT_URI, alarm.id),  
  6.             values, null, null);  
  7.   
  8.     long timeInMillis = calculateAlarm(alarm);  
  9.   
  10.     if (alarm.enabled) {  
  11.         // Disable the snooze if we just changed the snoozed alarm. This  
  12.         // only does work if the snoozed alarm is the same as the given  
  13.         // alarm.  
  14.         // TODO: disableSnoozeAlert should have a better name.  
  15.         disableSnoozeAlert(context, alarm.id);  
  16.   
  17.         // Disable the snooze if this alarm fires before the snoozed alarm.  
  18.         // This works on every alarm since the user most likely intends to  
  19.         // have the modified alarm fire next.  
  20.         clearSnoozeIfNeeded(context, timeInMillis);  
  21.     }  
  22.   
  23.     setNextAlert(context);  
  24.   
  25.     return timeInMillis;  
  26. }  

然后这里面也会调用到

[cpp] view plaincopy
  1. public static void setNextAlert(final Context context) {  
  2.     final Alarm alarm = calculateNextAlert(context);  
  3.     if (alarm != null) {  
  4.         enableAlert(context, alarm, alarm.time);  
  5.     } else {  
  6.         disableAlert(context);  
  7.     }  
  8. }  
calculateNextAlert(context);   //new 一个新的alarm 
然后继续调用到

     private static void enableAlert(Context context, final Alarm alarm,final long atTimeInMillis)

其中am.set(AlarmManager.RTC_WAKEUP, atTimeInMillis, sender);//这里是RTC_WAKEUP, 这就保证了即使系统睡眠了,都能唤醒,闹钟工作(android平台关机闹钟好像不行)

然后就调用到了AlarmManager.java 里面方法

[cpp] view plaincopy
  1. public void set(int type, long triggerAtTime, PendingIntent operation) {  
  2.     try {  
  3.         mService.set(type, triggerAtTime, operation);  
  4.     } catch (RemoteException ex) {  
  5.     }  
  6. }  

然后就调用到了AlarmManagerService.java  里面方法
[cpp] view plaincopy
  1. public void set(int type, long triggerAtTime, PendingIntent operation) {  
  2.         setRepeating(type, triggerAtTime, 0, operation);  
  3.     }  

然后继续调用
[cpp] view plaincopy
  1. public void setRepeating(int type, long triggerAtTime, long interval,   
  2.             PendingIntent operation) {  
  3. .....  
  4. synchronized (mLock) {  
  5.             Alarm alarm = new Alarm();  
  6.             alarm.type = type;  
  7.             alarm.when = triggerAtTime;  
  8.             alarm.repeatInterval = interval;  
  9.             alarm.operation = operation;  
  10.   
  11.             // Remove this alarm if already scheduled.  
  12.             removeLocked(operation);  
  13.   
  14.             if (localLOGV) Slog.v(TAG, "set: " + alarm);  
  15.   
  16.             int index = addAlarmLocked(alarm);  
  17.             if (index == 0) {  
  18.                 setLocked(alarm);  
  19.             }  
  20.         }  
  21.     }  

然后就调用到
[cpp] view plaincopy
  1. private void setLocked(Alarm alarm)  
  2.     {  
  3.     ......  
  4.     set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds);   //mDescriptor  这里的文件是 /dev/alarm  
  5.     .....  
  6. }  
这里就调用到jni了
private native void set(int fd, int type, long seconds, long nanoseconds);

这就调用到了com_android_server_AlarmManagerService.cpp 里面
[cpp] view plaincopy
  1. static JNINativeMethod sMethods[] = {  
  2.      /* name, signature, funcPtr */  
  3.     {"init""()I", (void*)android_server_AlarmManagerService_init},  
  4.     {"close""(I)V", (void*)android_server_AlarmManagerService_close},  
  5.     {"set""(IIJJ)V", (void*)android_server_AlarmManagerService_set},  
  6.     {"waitForAlarm""(I)I", (void*)android_server_AlarmManagerService_waitForAlarm},  
  7.     {"setKernelTimezone""(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone},  
  8. };  
set 对应的是android_server_AlarmManagerService_set, 具体是
[cpp] view plaincopy
  1. static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds)  
  2. {  
  3. #if HAVE_ANDROID_OS  
  4.     struct timespec ts;  
  5.     ts.tv_sec = seconds;  
  6.     ts.tv_nsec = nanoseconds;  
  7.       
  8.     int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts);  
  9.     if (result < 0)  
  10.     {  
  11.         LOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno));  
  12.     }  
  13. #endif  
  14. }  
然后ioctl 就调用到了alarm-dev.c

[cpp] view plaincopy
  1. static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)  
  2. {  
  3.     int rv = 0;  
  4.     unsigned long flags;  
  5.     struct timespec new_alarm_time;  
  6.     struct timespec new_rtc_time;  
  7.     struct timespec tmp_time;  
  8.     enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);  
  9.     uint32_t alarm_type_mask = 1U << alarm_type;  
  10.     printk(">>%s cmd == %d\n",__FUNCTION__,cmd);  
  11.     if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)  
  12.         return -EINVAL;  
  13.   
  14.     if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {  
  15.         if ((file->f_flags & O_ACCMODE) == O_RDONLY)  
  16.             return -EPERM;  
  17.         if (file->private_data == NULL &&  
  18.             cmd != ANDROID_ALARM_SET_RTC) {  
  19.             spin_lock_irqsave(&alarm_slock, flags);  
  20.             if (alarm_opened) {  
  21.                 spin_unlock_irqrestore(&alarm_slock, flags);  
  22.                 return -EBUSY;  
  23.             }  
  24.             alarm_opened = 1;  
  25.             file->private_data = (void *)1;  
  26.             spin_unlock_irqrestore(&alarm_slock, flags);  
  27.         }  
  28.     }  
  29.   
  30.     switch (ANDROID_ALARM_BASE_CMD(cmd)) {  
  31.     case ANDROID_ALARM_CLEAR(0):  
  32.         spin_lock_irqsave(&alarm_slock, flags);  
  33.         pr_alarm(IO, "alarm %d clear\n", alarm_type);  
  34.         alarm_try_to_cancel(&alarms[alarm_type]);  
  35.         if (alarm_pending) {  
  36.             alarm_pending &= ~alarm_type_mask;  
  37.             if (!alarm_pending && !wait_pending)  
  38.                 wake_unlock(&alarm_wake_lock);  
  39.         }  
  40.         alarm_enabled &= ~alarm_type_mask;  
  41.         spin_unlock_irqrestore(&alarm_slock, flags);  
  42.         break;  
  43.   
  44.     case ANDROID_ALARM_SET_OLD:  
  45.     case ANDROID_ALARM_SET_AND_WAIT_OLD:  
  46.         if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) {  
  47.             rv = -EFAULT;  
  48.             goto err1;  
  49.         }  
  50.         new_alarm_time.tv_nsec = 0;  
  51.         goto from_old_alarm_set;  
  52.   
  53.     case ANDROID_ALARM_SET_AND_WAIT(0):  
  54.     case ANDROID_ALARM_SET(0):  
  55.         if (copy_from_user(&new_alarm_time, (void __user *)arg,  
  56.             sizeof(new_alarm_time))) {  
  57.             rv = -EFAULT;  
  58.             goto err1;  
  59.         }  
  60. from_old_alarm_set:  
  61.         spin_lock_irqsave(&alarm_slock, flags);  
  62.         pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type,  
  63.             new_alarm_time.tv_sec, new_alarm_time.tv_nsec);  
  64.         alarm_enabled |= alarm_type_mask;  
  65.         alarm_start_range(&alarms[alarm_type],  
  66.             timespec_to_ktime(new_alarm_time),  
  67.             timespec_to_ktime(new_alarm_time));  
  68.         spin_unlock_irqrestore(&alarm_slock, flags);  
  69.         if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0)  
  70.             && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD)  
  71.             break;  
  72.         /* fall though */  
  73.     case ANDROID_ALARM_WAIT:  
  74.         spin_lock_irqsave(&alarm_slock, flags);  
  75.         pr_alarm(IO, "alarm wait\n");  
  76.         if (!alarm_pending && wait_pending) {  
  77.             wake_unlock(&alarm_wake_lock);  
  78.             wait_pending = 0;  
  79.         }  
  80.         spin_unlock_irqrestore(&alarm_slock, flags);  
  81.         rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);  
  82.         if (rv)  
  83.             goto err1;  
  84.         spin_lock_irqsave(&alarm_slock, flags);  
  85.         rv = alarm_pending;  
  86.         wait_pending = 1;  
  87.         alarm_pending = 0;  
  88.         spin_unlock_irqrestore(&alarm_slock, flags);  
  89.         break;  
  90.     case ANDROID_ALARM_SET_RTC:  
  91.         if (copy_from_user(&new_rtc_time, (void __user *)arg,  
  92.             sizeof(new_rtc_time))) {  
  93.             rv = -EFAULT;  
  94.             goto err1;  
  95.         }  
  96.         rv = alarm_set_rtc(new_rtc_time);  
  97.         spin_lock_irqsave(&alarm_slock, flags);  
  98.         alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;  
  99.         wake_up(&alarm_wait_queue);  
  100.         spin_unlock_irqrestore(&alarm_slock, flags);  
  101.         if (rv < 0)  
  102.             goto err1;  
  103.         break;  
  104.     case ANDROID_ALARM_GET_TIME(0):  
  105.         switch (alarm_type) {  
  106.         case ANDROID_ALARM_RTC_WAKEUP:  
  107.         case ANDROID_ALARM_RTC:  
  108.             getnstimeofday(&tmp_time);  
  109.             break;  
  110.         case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:  
  111.         case ANDROID_ALARM_ELAPSED_REALTIME:  
  112.             tmp_time =  
  113.                 ktime_to_timespec(alarm_get_elapsed_realtime());  
  114.             break;  
  115.         case ANDROID_ALARM_TYPE_COUNT:  
  116.         case ANDROID_ALARM_SYSTEMTIME:  
  117.             ktime_get_ts(&tmp_time);  
  118.             break;  
  119.         }  
  120.         if (copy_to_user((void __user *)arg, &tmp_time,  
  121.             sizeof(tmp_time))) {  
  122.             rv = -EFAULT;  
  123.             goto err1;  
  124.         }  
  125.         break;  
  126.   
  127.     default:  
  128.         rv = -EINVAL;  
  129.         goto err1;  
  130.     }  
  131. err1:  
  132.     return rv;  
  133. }  

alarm.c  里面实现了 alarm_suspend  alarm_resume 函数
就是如果系统没有suspend的时候,设置闹钟并不会往rtc 芯片的寄存器上写数据,因为不需要唤醒系统,所以闹钟数据时间什么的就通过上层写到设备文件/dev/alarm
里面就可以了,AlarmThread 会不停的去轮寻下一个时间有没有闹钟,直接从设备文件 /dev/alarm 里面读取
第二种,系统要是进入susupend的话,alarm 的alarm_suspend  就会写到下层的rtc芯片的寄存器上去, 然后即使系统suspend之后,闹钟通过rtc 也能唤醒系统。

这里就调用到了interface.c 里面   //这里面 int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 差不多 也是跟下面一样

[cpp] view plaincopy
  1. int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)  
  2. {  
  3. ....  
  4.     err = rtc->ops->set_time(rtc->dev.parent, tm);  
  5. ....  
  6. }  

然后set_time 就看到具体的是那个RTC芯片,这边我们是rtc-hym8563.c
然后就到了
[cpp] view plaincopy
  1. static int hym8563_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], __u16 len)  
  2. {  
  3.     int ret;   
  4.     ret = i2c_master_reg8_send(client, reg, buf, (int)len, RTC_SPEED);  
  5.     return ret;  
  6. }  

到此,闹钟时间就已经写到rtc 芯片的寄存器里面,第二个参数就是寄存器的名字,后面的buf就是要写入的时间,rtc芯片是额外供电的,所以系统suspend之后,系统kernel都关了,但是rtc里面还有电,寄存器里面数据还是有的(掉电就会丢失数据),所以闹钟到了,通过硬件中断机制就可以唤醒系统。

3.下面是系统唤醒之后,闹钟怎么工作的流程,简单阐述

[cpp] view plaincopy
  1.  private class AlarmThread extends Thread  
  2.     {  
  3.         public AlarmThread()  
  4.         {  
  5.             super("AlarmManager");  
  6.         }  
  7.           
  8.         public void run()  
  9.         {   
  10.         while (true)  
  11.             {  
  12.         int result = waitForAlarm(mDescriptor); //这里调用jni调用static jint android_server_AlarmManagerService_waitForAlarm,主要还是对 /dev/alarm  操作  
  13.         ....  
  14.         Alarm alarm = it.next();  
  15.                         try {  
  16.                             if (localLOGV) Slog.v(TAG, "sending alarm " + alarm);  
  17.                             alarm.operation.send(mContext, 0,  
  18.                                     mBackgroundIntent.putExtra(  
  19.                                             Intent.EXTRA_ALARM_COUNT, alarm.count),  
  20.                                     mResultReceiver, mHandler);  
  21.         ....  
  22.         }  
  23.   
  24.     }  
  25.       }  
  26.   
  27.   
  28. static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd)  
  29. {  
  30. #if HAVE_ANDROID_OS  
  31.     int result = 0;  
  32.       
  33.     do  
  34.     {  
  35.         result = ioctl(fd, ANDROID_ALARM_WAIT);  
  36.     } while (result < 0 && errno == EINTR);  
  37.       
  38.     if (result < 0)  
  39.     {  
  40.         LOGE("Unable to wait on alarm: %s\n", strerror(errno));  
  41.         return 0;  
  42.     }  
  43.       
  44.     return result;  
  45. #endif  
  46. }  
系统没有suspend的话直接走下面流程,如果suspend的话会被RTC唤醒,然后还是走下面的流程
AlarmManagerService  里面有个AlarmThread  会一直轮询 /dev/alarm文件,如果打开失败就直接返回,成功就会做一些动作,比如查找时间最近的
alarm,比如睡眠被闹钟唤醒的时候,这边就发一个intent出去,然后在AlarmReceiver.java里面弹出里面会收到就会调用下面的
        context.startActivity(alarmAlert);
然后弹出alarm  这个界面
        Class c = AlarmAlert.class;
其中public class AlarmAlert extends AlarmAlertFullScreen  所以系统睡眠之后被alarm唤醒弹出的alarm就是这边start的

[cpp] view plaincopy
  1. public class AlarmReceiver extends BroadcastReceiver {  
  2.   
  3.     /** If the alarm is older than STALE_WINDOW, ignore.  It 
  4.         is probably the result of a time or timezone change */  
  5.     private final static int STALE_WINDOW = 30 * 60 * 1000;  
  6.   
  7.     @Override  
  8.     public void onReceive(Context context, Intent intent) {  
  9.     .........  
  10.         Intent alarmAlert = new Intent(context, c);  
  11.         alarmAlert.putExtra(Alarms.ALARM_INTENT_EXTRA, alarm);  
  12.         alarmAlert.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK  
  13.                 | Intent.FLAG_ACTIVITY_NO_USER_ACTION);  
  14.         context.startActivity(alarmAlert);  
  15.     ........  
  16. }  

到这里alarm 就显示出来了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Pytorch神经网络实战案例】12 利用注意力机制的神经网络实现对FashionMNIST数据集图片的分类

1、掩码模式&#xff1a;是相对于变长的循环序列而言的&#xff0c;如果输入的样本序列长度不同&#xff0c;那么会先对其进行对齐处理&#xff08;对短序列补0&#xff0c;对长序列截断&#xff09;&#xff0c;再输入模型。这样&#xff0c;模型中的部分样本中就会有大量的零…

echarts自学笔记

学习echarts的总结 一、图表的实现 (1)首先将echarts.js引入为echarts提供一个DOM容器&#xff08;具有宽高&#xff09;为echarts配置参数:第一步&#xff1a;初始化DOM容器&#xff0c;用echarts.init()函数第二步&#xff1a; 配置数据选项var option{ title:{},//图表的标…

爬虫实战学习笔记_4 网络请求urllib3模块:发送GET/POST请求实例+上传文件+IP代理+json+二进制+超时

1 urllib3模块简介 urllib3是一个第三方的网络请求模块&#xff08;单独安装该模块&#xff09;&#xff0c;在功能上比Python自带的urllib强大。 1.1了解urllib3 urllib3库功能强大&#xff0c;条理清晰的用于HTTP客户端的python库&#xff0c;提供了很多Python标准库里所没…

Android wakelock 自上而下浅析

Wake Lock是一种锁的机制, 只要有人拿着这个锁,系统就无法进入休眠,可以被用户态程序和内核获得. 这个锁可以是有超时的或者是没有超时的,超时的锁会在时间过去以后自动解锁. 如果没有锁了或者超时了, 内核就会启动休眠的那套机制来进入休眠.PowerManager.WakeLock 有加锁和解锁…

C. Jon Snow and his Favourite Number DP + 注意数值大小

http://codeforces.com/contest/768/problem/C 这题的数值大小只有1000&#xff0c;那么可以联想到&#xff0c;用数值做数组的下标&#xff0c;就是类似于计数排序那样子。。 这样就可以枚举k次操作&#xff0c;然后for (int i 0; i < 1025; i)&#xff0c;也就是O(1000 *…

【Pytorch神经网络理论篇】 21 信息熵与互信息:联合熵+条件熵+交叉熵+相对熵/KL散度/信息散度+JS散度

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

vim 设置支持鼠标

在vim模式 下 :set mousea 也可以把上面的语句去掉起始的冒号放到 .vimrc 文件中 打开一个vim 输入:echo $VIM 这里就会打印出vimrc的位置 vim的一些配置相关 http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html

POJ 2395 Out of Hay

http://poj.org/problem?id2395 裸最小生成树 输出树中最大cost的边值 直接prim 1 #include <iostream>2 #include <stdio.h>3 #include <string.h>4 #include <queue>5 #include <algorithm>6 #define READ() freopen("in.txt", &qu…

【Pytorch神经网络理论篇】 22 自编码神经网络:概述+变分+条件变分自编码神经网络

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

Android关机闹钟实现

时间转换网站:http://tool.chinaz.com/Tools/unixtime.aspx 1、apk层 这个还是比较简单的,百度一下就可以看到apk的代码,我之前也有贴出来过还是看一下核心代码吧。 写好的apk(里面有Android.mk文件 加入system/app/下面进行编译):http://download.csdn.net/detail/…

CI开发笔记

CI中的mvc&#xff1a; 访问url使用的是passinfo//就是类似一个文件夹的方式 入口文件.php/控制器/方法&#xff08;动作&#xff09; 控制器&#xff1a; 1.不用加后缀 直接一个单词.php 文件名全部小写 2.控制器是直接或者间接的继承自CI_Controller 3.控制器中对方法的要求…

【Pytorch神经网络实战案例】13 构建变分自编码神经网络模型生成Fashon-MNST模拟数据

1 变分自编码神经网络生成模拟数据案例说明 变分自编码里面真正的公式只有一个KL散度。 1.1 变分自编码神经网络模型介绍 主要由以下三个部分构成&#xff1a; 1.1.1 编码器 由两层全连接神经网络组成&#xff0c;第一层有784个维度的输入和256个维度的输出&#xff1b;第…

linux tar 使用

tar tar 主要用于创建归档文件&#xff0c;和解压归档文件&#xff0c;其本身是没有压缩功能的&#xff0c;但可以调用 gzip 、 bzip2 进行压缩处理。 参数解释&#xff1a; -c 创建归档 -x 解压归档 -v 显示处理过程 -f 目标文件&#xff0c;其后必须紧跟 目标文件 -j 调用 bz…

【Pytorch神经网络实战案例】14 构建条件变分自编码神经网络模型生成可控Fashon-MNST模拟数据

1 条件变分自编码神经网络生成模拟数据案例说明 在实际应用中&#xff0c;条件变分自编码神经网络的应用会更为广泛一些&#xff0c;因为它使得模型输出的模拟数据可控&#xff0c;即可以指定模型输出鞋子或者上衣。 1.1 案例描述 在变分自编码神经网络模型的技术上构建条件…

hibernate持久化对象

转载于:https://www.cnblogs.com/jianxin-lilang/p/6440101.html

MTK8127添加一个新的camera驱动

简单总结一下 mtk 的all in one 这个文档台强大了,如果第一次配置摄像头,可以找这个文档来看。 1、kernel层添加 +mediatek/custom/mid713l_lp_lvds/kernel/imgsensor/bf3703_yuv/ 驱动文件夹 +bf3703yuv_CameraCustomized.h +bf3703yuv_Camera_Sensor_para.h +bf3…

【Pytorch神经网络理论篇】 23 对抗神经网络:概述流程 + WGAN模型 + WGAN-gp模型 + 条件GAN + WGAN-div + W散度

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

[haoi2011]防线修建

动态加点维护凸包。 论STL的熟练运用。 #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<iostream> #include<string> #include<map> #include<set> #include<cstdlib> #include<…

【Pytorch神经网络实战案例】15 WGAN-gp模型生成Fashon-MNST模拟数据

1 WGAN-gp模型生成模拟数据案例说明 使用WGAN-gp模型模拟Fashion-MNIST数据的生成&#xff0c;会使用到WGAN-gp模型、深度卷积GAN(DeepConvolutional GAN&#xff0c;DCGAN)模型、实例归一化技术。 1.1 DCGAN中的全卷积 WGAN-gp模型侧重于GAN模型的训练部分&#xff0c;而DCG…

Android启动过程深入解析

转载自&#xff1a;http://blog.jobbole.com/67931/ 当按下Android设备电源键时究竟发生了什么&#xff1f;Android的启动过程是怎么样的&#xff1f;什么是Linux内核&#xff1f;桌面系统linux内核与Android系统linux内核有什么区别&#xff1f;什么是引导装载程序&#xff1…