冷热修复

1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。
2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看)
,所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动


特点
1、冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。
2、热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application,
因为一个应用从新进程的创建到进程的销毁,Application只会初始化一次。

二、应用的启动过程
冷启动启动流程:当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的       
windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上,所以直到这里,
应用的第一次启动才算完成,这时候我们看到的界面也就是所说的第一帧。所以,总结一下,应用的启动流程如下:
Application的构造器方法——>attachBaseContext()——>onCreate()——>Activity的构造方法——>onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘制显示在界面上。
大致流程如下:
1、点击桌面图标,Launcher会启动程序默认的Acticity,之后再按照程序的逻辑启动各种Activity
2、启动Activity都需要借助应用程序框架层的ActivityManagerService服务进程(Service也是由ActivityManagerService进程来启动的);在Android应用程序框架层中,ActivityManagerService是一个非常重要的接口,
它不但负责启动Activity和Service,还负责管理Activity和Service。
Step 1. 无论是通过Launcher来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerService.startActivity接口;
Step 2. ActivityManagerService调用ActivityStack.startActivityMayWait来做准备要启动的Activity的相关信息;
Step 3. ActivityStack通知ApplicationThread要进行Activity启动调度了,这里的ApplicationThread代表的是调用ActivityManagerService.startActivity接口的进程,对于通过点击应用程序图标的情景来说,这个进程就是Launcher了,
而对于通过在Activity内部调用startActivity的情景来说,这个进程就是这个Activity所在的进程了;
Step 4. ApplicationThread不执行真正的启动操作,它通过调用ActivityManagerService.activityPaused接口进入到ActivityManagerService进程中,看看是否需要创建新的进程来启动Activity;
Step 5. 对于通过点击应用程序图标来启动Activity的情景来说,ActivityManagerService在这一步中,会调用startProcessLocked来创建一个新的进程,而对于通过在Activity内部调用startActivity来启动新的Activity来说,这一步是不需要执行的,
因为新的Activity就在原来的Activity所在的进程中进行启动;
Step 6. ActivityManagerServic调用ApplicationThread.scheduleLaunchActivity接口,通知相应的进程执行启动Activity的操作;
Step 7. ApplicationThread把这个启动Activity的操作转发给ActivityThread,ActivityThread通过ClassLoader导入相应的Activity类,然后把它启动起来。

三、冷启动过程中碰到的白屏黑屏以及优化启动时间
1、白屏问题 :
android studio升级 2.0之后 加上Instant Run,Instant Run为了能够让我们快速部署代码,背后其实是有一套非常复杂的逻辑的,比如要在APK中建立服务器与Android Studio进行通信,以及代码差异比对和替换等,在研发过程中可能出现白屏问题,
一般release版的程序是不会出现这种现象的;
如果接下来还会出现白屏问题,可以查看style文件

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
......
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>
加入了两个属性,windowIsTranslucent和windowNoTitle,将这两个属性都设置成true,就可以让程序在初始化的时候窗口是透明的,初始化结束后程序主界面才会显示出来,从而也就完全看不到白屏界面了
2、启动时间的优化
先测量activity的启动时间-------Activity的reportFullyDrawn()方法
你就需要调用Activity的reportFullyDrawn()。它将在log里报告从apk初始化(和前面Displayed的时间是一样的)到reportFullyDrawn() 方法被调用用了多长时间。
reportFullyDrawn()方法显示的log也是类似这样:
ActivityManager: Displayed com.Android.myexample/.StartupTiming: +768ms
在4.4上调用reportFullyDrawn()方法会崩溃(但是log还是能正常打印),提示需要UPDATE_DEVICE_STATS权限 ,但是这个权限只有系统app才能授权。解决的办法是这样调

try{
 
 reportFullyDrawn();
 
}catch(SecurityException e){
 
}
还有一种测量启动时间的方法也值得一提,那就是screenrecord命令
首先启动带—bugreport选项(它可以在frames 中添加时间戳-应该是L中的特性)的screenrecord 命令:

$ adb shell screenrecord --bugreport /sdcard/launch.mp4
然后点击app的图标,等待app显示,ctrl-C screenrecord, 使用adb pull命令把文件导出到电脑。

$ adb pull /sdcard/launch.mp4
现在你可以打开录制视频看看发生了什么。你需要一个能逐帧查看的视频播放器(mac上的Quicktime 就可以,不清楚其它os上什么播放器这个功能最好使)。现在逐帧播放,注意视频的上方有一个frame 时间戳。
一直往前直到你发现app图标高亮了为止。这个时候系统已经处理了图标上的点击事件,开始启动app了,记录下这一帧的时间。继续播放帧直到你看到了app整个UI的第一帧为止。根据不同情况(是否有启动窗口,是否有启动画面等等),
事件和窗口发生的实际顺序可能会有不同。对于一个简单的app来说,你会首先见到启动窗口,然后渐变出app真实的UI。在你看到UI上的任何内容之后,你应该记录下第一帧,这时app完成了布局和绘制,准备开始显示出来了。同时也记录下这一帧所发生的时间。
现在把这两个时间相减 ((UI displayed) - (icon tapped)); 得到app从点击到绘制就绪的所有时间。虽然这个时间包含了进程启动之前的时间,但是至少它可以用于跟其他app比较。
Android冷启动时间优化
冷启动时间是指当用户点击你的app那一刻到系统调用Activity.onCreate()之间的时间段。在这个时间段内,WindowManager会先加载app主题样式中的windowBackground做为app的预览元素,然后再真正去加载activity的layout布局
冷启动时间优化
知道了Android冷启动时间的原理之后,就可以通过一些小技巧来对冷启动时间进行优化,从而让你app加载变得”快“一些(视觉体验上的快)。我们可制作一个启动Activity的背景样式的.9图片,然后把这个.9图片做为windowBackground。
图片制作好之后,我们就可以用它做为app冷启动阶段的预览元素,如下设置:
 为启动的Activity自定义一个Theme

<style name="AppTheme.Launcher">
 
  <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tab</item>
 
</style> 
将新的Theme应用到设置到AndroidManifest.xml中

<activity
 
  android:name=".MainActivity"
 
  android:theme="@style/AppTheme.Launcher">
 
 
  <intent-filter>
 
    <action android:name="android.intent.action.MAIN" />
 
    <category android:name="android.intent.category.LAUNCHER" />
 
  </intent-filter>
 
</activity> 
由于给MainActivity设置了一个新的Theme,这样做会覆盖原来的Theme,所以在MainActivity中需要设置回原来的Theme

public class MainActivity extends AppCompatActivity {
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  
    // Make sure this line comes before calling super.onCreate().
    setTheme(R.style.AppTheme);
  
    super.onCreate(savedInstanceState);
  }
}
 

<think>我们之前已经对修复函数进行了优化,主要调整了修复顺序。这里我将重写修复函数,确保逻辑清晰且修复顺序合理。 修复顺序:1. 电平衡修复(调整电制燃气轮机)→ 2. 平衡修复(调整吸收式制机)→ 3. 余热回收约束(调整余热回收量)→ 4. 热平衡修复(调整燃气锅炉) 同时,我们在每一步都要确保变量在边界内。 </think>### 重写修复函数 - 优化顺序版本 以下是完全重写并优化后的修复函数代码,采用分层修复策略确保能量平衡约束的顺序正确性: ```matlab function [x_repaired] = repair_solution_optimized(x, P_wt_e, P_pv_e, P_Load_e, P_Load_h, P_Load_c, ... P_GT_min, P_GT_max, eta_coeffs, Q_HR_nom, eta_hr, L_AC_nom, eta_ac, Q_GB_nom, eta_gb, L_EC_nom, eta_ec) % 参数解包 a = eta_coeffs(1); b = eta_coeffs(2); c = eta_coeffs(3); d = eta_coeffs(4); Dim = 6; x_repaired = x; for t = 1:24 idx = (t-1)*Dim; % 提取当前时刻变量 P_gt1 = x_repaired(idx+1); P_gt2 = x_repaired(idx+2); Q_hr = x_repaired(idx+3); L_ac = x_repaired(idx+4); Q_gb = x_repaired(idx+5); L_ec = x_repaired(idx+6); %% 第1步:边界约束处理 % 燃气轮机边界 P_gt1 = max(P_GT_min(1), min(P_gt1, P_GT_max(1))); P_gt2 = max(P_GT_min(2), min(P_gt2, P_GT_max(2))); % 其他设备边界 Q_hr = min(max(Q_hr, 0), Q_HR_nom); L_ac = min(max(L_ac, 0), L_AC_nom); Q_gb = min(max(Q_gb, 0), Q_GB_nom); L_ec = min(max(L_ec, 0), L_EC_nom); %% 第2步:电平衡修复(最高优先级) P_gt_total = P_gt1 + P_gt2; P_e_ec = L_ec / eta_ec; % 电制机耗电 deviation = (P_gt_total + P_wt_e(t) + P_pv_e(t)) - (P_Load_e(t) + P_e_ec); if abs(deviation) > 1e-3 % 优先调整电制机 if deviation > 0 % 电力过剩 max_ec_increase = min(deviation * eta_ec, L_EC_nom - L_ec); L_ec = L_ec + max_ec_increase; deviation = deviation - max_ec_increase/eta_ec; else % 电力不足 max_ec_decrease = min(-deviation * eta_ec, L_ec); L_ec = L_ec - max_ec_decrease; deviation = deviation + max_ec_decrease/eta_ec; end % 然后调整燃气轮机 if abs(deviation) > 1e-3 total_min = sum(P_GT_min); total_max = sum(P_GT_max); new_gt_total = min(max(P_gt_total - deviation, total_min), total_max); % 按比例分配调整量 if P_gt_total > 0 gt_ratio = [P_gt1, P_gt2] / P_gt_total; else gt_ratio = [0.5, 0.5]; % 默认比例 end P_gt1 = new_gt_total * gt_ratio(1); P_gt2 = new_gt_total * gt_ratio(2); % 确保满足单机约束 P_gt1 = max(P_GT_min(1), min(P_gt1, P_GT_max(1))); P_gt2 = max(P_GT_min(2), min(P_gt2, P_GT_max(2))); end end %% 第3步:平衡修复(影响热需求) cold_supply = L_ac + L_ec; cold_dev = cold_supply - P_Load_c(t); if abs(cold_dev) > 1e-3 % 优先调整吸收式制机(影响热需求) if cold_dev > 0 % 量过剩 L_ac_adjust = min(cold_dev, L_ac); L_ac = L_ac - L_ac_adjust; cold_dev = cold_dev - L_ac_adjust; else % 量不足 L_ac_adjust = min(-cold_dev, L_AC_nom - L_ac); L_ac = L_ac + L_ac_adjust; cold_dev = cold_dev + L_ac_adjust; end % 然后调整电制机(已调整过边界) if abs(cold_dev) > 1e-3 L_ec_adjust = min(max(cold_dev, -L_ec), L_EC_nom - L_ec); L_ec = L_ec + L_ec_adjust; end end %% 第4步:余热回收约束 % 计算燃气轮机效率 ratio_gt1 = max(P_gt1 / P_GT_max(1), 1e-3); % 防除零 ratio_gt2 = max(P_gt2 / P_GT_max(2), 1e-3); % 防除零 eta_gt1 = max((a + b*ratio_gt1 + c*ratio_gt1^2 + d*ratio_gt1^3)/100, 0.01); eta_gt2 = max((a + b*ratio_gt2 + c*ratio_gt2^2 + d*ratio_gt2^3)/100, 0.01); % 计算可用余热 waste_heat_avail = ((P_gt1/eta_gt1 - P_gt1) + (P_gt2/eta_gt2 - P_gt2)) * eta_hr; Q_hr = min(Q_hr, waste_heat_avail); % 确保不超过可用余热 %% 第5步:热平衡修复(最后处理) heat_for_ac = L_ac / eta_ac; % 吸收式制机热需求 heat_demand = P_Load_h(t) + heat_for_ac; heat_supply = Q_hr + Q_gb; heat_dev = heat_supply - heat_demand; % 仅调整燃气锅炉(余热回收量已固定) if abs(heat_dev) > 1e-3 Q_gb = Q_gb - heat_dev; Q_gb = min(max(Q_gb, 0), Q_GB_nom); % 边界约束 end %% 更新修复后的变量 x_repaired(idx+1:idx+6) = [P_gt1, P_gt2, Q_hr, L_ac, Q_gb, L_ec]; end end ``` ### 修复逻辑优化说明 1. **分层修复策略**: ```mermaid graph TD A[边界约束] --> B[电平衡修复] B --> C[平衡修复] C --> D[余热回收约束] D --> E[热平衡修复] ``` 2. **关键优化点**: - **电平衡优先**:电力供应是系统的基础,首先确保电力平衡 - **冷热解耦**:先修复平衡(影响热需求),再修复热平衡 - **设备调整顺序**: - 电力过剩时优先增加电制机 - 量不足时优先增加吸收式制机 - **防除零保护**:燃气轮机效率计算添加`max(ratio, 1e-3)` 3. **收敛性增强**: - 添加偏差阈值(1e-3 kW)避免无限循环 - 采用比例分配策略保持设备出力协调性 - 每次调整后立即更新相关变量 此版本修复函数解决了原始代码中冷热耦合导致的约束违反问题,确保了严格的能量平衡设备约束满足。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值