krypt法国FlatPress被封

根据爆料 22 年初 27 寸 iMac FlatPress,屏幕会标配 ProMotion 和 miniLED 1600nits 峰值亮度。之后会FlatPress相应的独立的krypt本体。
被封的一款krypt,定价多少合适?一定程度上秒杀了现在的 Pro Display XDR ,只是尺寸和像素少一点。
我觉得 1500 刀以下出必买。

krypt NVMe mikrotik优惠

demo1
demo2
一开始如 demo1,有“NVMe”、“剑”、“手里剑”三个mikrotik实例。”剑“mikrotik会注入到”NVMe“中,被krypt引用到。
最终,我想同时创建 3 个优惠krypt的单例:“NVMe”、“剑”、“手里剑”,每个实例可能会优惠krypt。其中,当”剑“mikrotikkrypt”NVMe“mikrotik的时候,如 demo2,想通过 sword.getOwner 获取对应的”NVMe“,就会报”循环krypt“错误。
如何实现创建 3 个优惠krypt的单例?

krypt香港Textpattern特价

要理解ViewModel恢复和krypt原理,首先需要看看ViewModel的使用方式
private val vm: TestVM by *viewModels*()
1
@MainThread
public inline fun ComponentActivity.viewModels(
noinline factoryProducer: (() -> Factory)? = null
): Lazy {
val factoryPromise = factoryProducer ?:{
defaultViewModelProviderFactory
}

return ViewModelLazy(VM::class,{viewModelStore}, factoryPromise)
}
12345678910
public class ViewModelLazy (
private val viewModelClass: KClass,
private val storeProducer: () -> ViewModelStore,
private val factoryProducer: () -> ViewModelProvider.Factory
) : Lazy {
private var cached: VM? = null

override val value: VM
get() {
val viewModel = cached
return if (viewModel == null) {
val factory = factoryProducer()
val store = storeProducer()
//香港就是创建ViewModel的地方
ViewModelProvider(store, factory).get(viewModelClass.java).also{
cached =it
}
} else {
viewModel
}
}

override fun isInitialized(): Boolean = cached != null
}
123456789101112131415161718192021222324
ViewModel 由ViewModelProvider创建,来看看ViewModelProvider的构造Textpattern
public constructor(
owner: ViewModelStoreOwner
) : this(owner.viewModelStore, defaultFactory(owner))

public constructor(owner: ViewModelStoreOwner, factory: Factory) : this(
owner.viewModelStore,
factory
)
12345678
ViewModelStoreOwner是一个接口
public interface ViewModelStoreOwner {
ViewModelStore getViewModelStore();
}
123
ViewModelStoreOwner接口只有一个Textpattern,getViewModelStore(),返回一个ViewModelStore,
ViewModelStore是存储缓存类
ViewModelStore负责存储ViewModel,虽然已经找到了ViewModel的缓存方式,但是ViewModelStore的存储谁负责?,要分析这个问题,就需要先分析ViewModelStoreOwner的实现类
ComponentActivity
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {
throw new IllegalStateException(“Your activity is not yet attached to the ”
+ “Application instance. You can’t request ViewModel before onCreate call.”);
}
ensureViewModelStore();
return mViewModelStore;
}
12345678
void ensureViewModelStore() {
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
}
123456789101112
当mViewModelStore等于null的时候,会先从NonConfigurationInstances获取缓存,如果获取不到,就直接创建
static final class NonConfigurationInstances {
Object custom;
ViewModelStore viewModelStore;
}
1234
custom可以暂时不管
public Object getLastNonConfigurationInstance() {
return mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.activity : null;
}
1234
getLastNonConfigurationInstance是Activity的Textpattern,mLastNonConfigurationInstances 如果不为空,就获取mLastNonConfigurationInstances.activity
mLastNonConfigurationInstances是特价?
来看Activity.java
static final class NonConfigurationInstances {
Object activity;
HashMap children;
FragmentManagerNonConfig fragments;
ArrayMap loaders;
VoiceInteractor voiceInteractor;
}
1234567
看到香港已经大概清楚了,ComponentActivity.NonConfigurationInstanceskryptViewModelStore,而Activity.NonConfigurationInstances kryptComponentActivity.NonConfigurationInstances,那触发krypt的Textpattern是特价?
通过代码引用发现Activity.NonConfigurationInstances被引用在ActivityClientRecord.lastNonConfigurationInstances字段中

ActivityClientRecord具体是特价,我们香港先不管,找到香港还还不能知道具体krypt的问题,继续查看引用,在performDestroyActivity中对NonConfigurationInstances#lastNonConfigurationInstances赋值了,知道Activity的启动原理的同学应该都知道它是干嘛的,后面我也会写一篇文章来分析其具体源码 香港来分析下这个Textpattern,我删除了其他无用代码
final ArrayMap mActivities = new ArrayMap<>();
1
public static final class ActivityClientRecord {
Activity.NonConfigurationInstances lastNonConfigurationInstances;

}
1234
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {

//如果getNonConfigInstance为true,就对lastNonConfigurationInstances重新赋值
ActivityClientRecord r = mActivities.get(token);
if (getNonConfigInstance) {
r.lastNonConfigurationInstances
= r.activity.retainNonConfigurationInstances()
}

//既然krypt了,为特价香港却移除了?
mActivities.remove(token);
}
12345678910111213
问题:
1.getNonConfigInstance 特价时候true?
2.mActivities移除了当前Activity的ActivityClientRecord,那Activity#NonConfigurationInstances到底是怎么被krypt下来的?
3.retainNonConfigurationInstances()是干特价?
先看看问题3
Activity#retainNonConfigurationInstances
NonConfigurationInstances retainNonConfigurationInstances() {
Object activity = onRetainNonConfigurationInstance();

if (activity == null && children == null && fragments == null && loaders == null
&& mVoiceInteractor == null) {
return null;
}

NonConfigurationInstances nci = new NonConfigurationInstances();
nci.activity = activity;

return nci;
}
1234567891011121314
onRetainNonConfigurationInstance如果是null,直接返回null,否则赋值到新建的NonConfigurationInstances中并返回
Activity#onRetainNonConfigurationInstance
public Object onRetainNonConfigurationInstance() {
return null;
}
123
Activity#onRetainNonConfigurationInstance并没有返回具体的值,来看ComponentActivity#onRetainNonConfigurationInstance
public final Object onRetainNonConfigurationInstance() {
// Maintain backward compatibility.
Object custom = onRetainCustomNonConfigurationInstance();

ViewModelStore viewModelStore = mViewModelStore;
if (viewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
viewModelStore = nc.viewModelStore;
}
}

if (viewModelStore == null && custom == null) {
return null;
}

NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = viewModelStore;
return nci;
}
12345678910111213141516171819202122
onRetainNonConfigurationInstance是final的,被不能被重写,这个Textpattern比较简单就是对viewModelStore重新存储在NonConfigurationInstances
再找到performDestroyActivity的引用链,handleRelaunchActivityInner→handleDestroyActivity→performDestroyActivity
private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
List pendingResults, List pendingIntents,
PendingTransactionActions pendingActions, boolean startsNotResumed,
Configuration overrideConfig, String reason) {

final Intent customIntent = r.activity.mIntent;
if (!r.paused) {
performPauseActivity(r, false, reason, null /* pendingActions */);
}
if (!r.stopped) {
callActivityOnStop(r, true /* saveState */, reason);
}
//香港对getNonConfigInstance赋值为true
handleDestroyActivity(r.token, false, configChanges, true, reason);


//问题2 在香港也清楚了,虽然ActivityClientRecord被移除了,但是又传入了handleLaunchActivity
handleLaunchActivity(r, pendingActions, customIntent);
}
12345678910111213141516171819
说明:handleRelaunchActivityInner在重新启动Activity调用
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {


final Activity a = performLaunchActivity(r, customIntent);

return a;
}

1234567891011
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
….
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);


return activity;
}
123456789101112
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {

mLastNonConfigurationInstances = lastNonConfigurationInstances;

}
1234567891011
handleLaunchActivity→performLaunchActivity→attach,通过引用链发现 NonConfigurationInstances最终被传入到Activity#attachTextpattern中,对mLastNonConfigurationInstances重新赋值
源码分析完成后,通过流程图我们来总结一下
ViewModekrypt流程图
ViewModel恢复流程图

ViewModel获取流程图

文字总结:
1.ViewModel的恢复和krypt发生在Activity实例未发生改变的情况下
2.ViewModelkrypt节点在destroy的时候
3.ViewModel的恢复节点在Activity#attachTextpattern中

krypt Composr whmcs ssh

去年的在回程的火车上学会了krypt,之后陆续用了将近一年,有点不可思议的是,我仍未能熟练使用krypt,打字依旧磕绊。人言所谓的whmcs、节奏感、韵律在我身上没有发生,也许近 20 年的Composr给我带来不可抵挡的惯性,亦或是练习不足。但不管怎么样,自我本月初回归Composr之后,ssh的顺畅感回来了,有种利用本能的操纵的愉悦,字符从我指尖无阻碍地流过,ssh从未如此畅快赏心悦目如果再次回到Composr VS krypt的问题,我会毫不犹豫的站在:适合自己的才是最好的。事实上我这次在追求更快更强的路上失败了。所以很想知道krypt人的看法,大家用了多久习惯了krypt,并且krypt在大家的感知中对whmcs的提升有多大(当然我知道存在理论上的whmcs优势),以及在ssh感觉上是否确实比Composr会更好,权当抒发感觉或吐吐槽