wyw 发布的文章

转折关系

中心理解:

要找标志词

  • 但是、可是、然而、却、不过、其实、事实上、实际上 等
  • 殊不知、截然不同、迥然不同、全新的研究、一种误读、遗憾的是、可惜的是、则不然

转折之后是重点,转折之前的不重要,只看标志词后面的

语句排序:

  • 转折词单独出现,一般不作首句
  • 通过转折词可捆绑语句(转折前后意思相反的两句)

解题步骤:1、看首句、找捆绑、定顺序、比尾句
2、识别转折线索
3、排除转折首句,寻找转折捆绑

逻辑填空:

  • 时间对比词,如最初、后来、全新等
  • 无标志词,语义上相反

核心考点:转折前后意思相反
解题步骤:1、找到标志识别转折
2、勾画已知核心信息
3、预判反义词做验证

因果关系

标志词

  • 所以、因此、因而、故而、于是、导致、使得、可见、看来等
  • 鉴于此、如此一来、这么一想、可以说等
  • 常考结构:引入+尾句得出结论(常见)、引入+结论+解释说明、引入+结论+转折、引入+结论+同时

中心理解:

通过因果标志词,确定结论是重点(结论比原因重要)。
把握结论是重点:1、找到标志识别因果
2、勾画已知核心信息
3、找准结论词之后的核心话题

逻辑填空:

横线前后构成因果关系
解题步骤:1、找到标志识别因果
2、勾画已知核心信息
3、根据因果标志词判断前后因果关系

必要条件关系

问题和对策,优先选对策
标志词:

  • 只有A才B
  • 应该、应当、必须、需要、应、须,要
  • 通过/采取....手段/途径/措施/方法/方式/渠道,才能....
  • 前提、基础、保障

怎么找对策:
1、标志词直接提对策:应该....
2、反面论证提对策:如果/倘若/一旦....+不好的结果
3、对策在选项中:文段为“提出问题+分析问题”,“解决问题的对策”可以作为答案

中心理解:

1、找到标志识别对策
2、勾画已知核心信息
3、识别总句核心话题秒选

并列关系

文段特征:
1、包含并别关联词:同时、此外、另外、也...
2、句式相同或相近
3、按照时间顺序展开
4、无标志,围绕相同话题论述
并列文段全都是重点,需要全部概括

中心理解:(把握全面概括这一考点)

1、有标志找标志词识别文段
2、没有标志就全面概括,找准相同话题
3、带着核心话题秒选

观点+解释说明

观点类型:结论;对策;评价
解释说明类型:1、举例说明:比如、例如、人名、地名、作品、事件等
2、数据资料:数字凭据、调查报告等
3、原因解释:因为、由于
4、正反论证:正说说,反说说,换种说法再说说
5、并列分述:通过并列结构进行分述

中心理解:

通过识别观点+解释说明结构,把握观点是文段重点,直接秒选
解题步骤:1、识别观点+解释说明结构
2、排除解释说明,非重点的表述,帮助确定中心
3、带着中心句核心话题秒选

语句排序:

通过标志词给出解题逻辑线索,主要考察叙事逻辑顺序
注意:1、比如、例如、就像、类似、因为、由于、即、换句话说、具体而言
2、解释说明一般不做首句
3、观点在前解释说明在后
解题步骤:把握观点+解释说明确定逻辑顺序
1、看首句、找捆绑
2、勾画解释说明标志词
3、根据标志词直接确定顺序或前后同义替换

主题词

主题词标志:1、中心句围绕的核心话题,一般前有引入或后有解释说明
2、每句话都围绕的相同话题
一般主题词都是名词、双引号注意
必备大招:文段围绕的核心话题、文段要围绕其展开
注意:1、扩大缩小偷换都不选
2、两个主题词要找全,常见干扰选项为主题词片面

中心理解:把握文段核心话题快速秒选

1、有中心句就先寻找中心句,中心句围绕的核心话题就是主题词
2、没有中心句,看每句话都围绕的相同话题
3、带着主题词(核心话题)秒选

感情色彩

感情色彩区分:1、褒义 成果
2、贬义 后果
3、中性 结果

逻辑填空:把握所填词语和文段感情色彩保持一致

1、略读文段判断感情色彩
2、对比选项排除不同感情色彩
3、确定感情色彩一致且无其他干扰选项秒选

形象化表达

正确答案用比喻、拟人的修辞手法进行加工

中心理解:

三大特点:1、契合文段中心
2、吸引读者
3、短小精悍
重点关注比喻、拟人的修辞手法
1、找中心句,优选契合中心
2、重点关注选项双引号

语句填空

注意选项特征:优先把握主题词,形象化表达不是“花瓶”,可能隐含文段中重要的关系
重点关注形象表达
1、找中心句,优先把握主题词
2、根据文段中的隐藏提示找形象化的转述

逻辑填空

横线前后出现比喻,拟人等修辞手法,表达得生动形象
注意:形象表达标志词:有如、就像、类似、恰似、有异曲同工之妙、“”
把握形象表达秒选
1、横线前后寻找形象表达标志词
2、根据标志词提示找形象化的转述

选项分组

题型:选项出现话题逻辑一致选项
分组原则:1、2:1:1分组原则
2、2:2分组原则
3、1:3分组原则

通过选项话题逻辑线索,帮助排除选项提高选题速度
1、2:1:1,若两个选项极其接近,或话题相同逻辑一致,则正确答案在这两个选项中出现的概率极高
2、2:2,四个选项根据话题或者形式可以两两分组,分组后带着差异有针对性到文段寻找,方可快速排除两个选项
3、1:3,从形式或内容上,与其他三个选项格格不入的词,通常是凑数的,一为易错项

优选语义丰富技巧

逻辑填空:

提醒特征:不同选项出现一样的字
技巧:1、实词拆字组词a=b+c,优选a
2、成语:字形拆分或语义拆分
秒题思维:1、观察选项,相同字数较多
2、拆字组词或字形语义拆分,优选语义丰富项

在线生成图网站

软件设计领域图表类型

1. 类图 (Class Diagram)

  • 用途:展示系统的静态结构
  • 展示内容

    • 类及其属性、方法
    • 类之间的关系(继承、实现、组合、聚合、关联等)
    • 类的可见性和访问修饰符
  • 适用场景

    • 系统架构设计
    • 代码结构分析
    • 面向对象设计

2. 时序图 (Sequence Diagram)

  • 用途:展示对象之间的交互顺序
  • 展示内容

    • 对象之间的消息传递
    • 方法调用顺序
    • 时间顺序
    • 同步/异步调用
  • 适用场景

    • 业务流程分析
    • 系统交互设计
    • 性能分析

3. 组件图 (Component Diagram)

  • 用途:展示系统的物理结构
  • 展示内容

    • 系统组件
    • 组件间依赖
    • 接口定义
    • 部署关系
  • 适用场景

    • 系统架构设计
    • 模块划分
    • 部署规划

4. 活动图 (Activity Diagram)

  • 用途:展示业务流程
  • 展示内容

    • 活动流程
    • 决策点
    • 并行活动
    • 条件分支
  • 适用场景

    • 业务流程设计
    • 工作流分析
    • 复杂逻辑梳理

5. 状态图 (State Diagram)

  • 用途:展示对象状态变化
  • 展示内容

    • 对象状态
    • 状态转换
    • 触发条件
    • 状态行为
  • 适用场景

    • 状态机设计
    • 生命周期管理
    • 复杂状态分析

6. 用例图 (Use Case Diagram)

  • 用途:展示系统功能需求
  • 展示内容

    • 系统功能
    • 用户角色
    • 功能关系
    • 系统边界
  • 适用场景

    • 需求分析
    • 功能规划
    • 用户交互设计

7. 部署图 (Deployment Diagram)

  • 用途:展示系统部署结构
  • 展示内容

    • 物理节点
    • 部署组件
    • 网络关系
    • 硬件配置
  • 适用场景

    • 系统部署规划
    • 硬件配置设计
    • 网络架构设计

8. 包图 (Package Diagram)

  • 用途:展示代码组织结构
  • 展示内容

    • 包结构
    • 包依赖
    • 模块划分
    • 代码组织
  • 适用场景

    • 代码架构设计
    • 模块划分
    • 依赖管理

9. 对象图 (Object Diagram)

  • 用途:展示系统在特定时刻的对象状态
  • 展示内容

    • 对象实例
    • 对象关系
    • 属性值
    • 运行时状态
  • 适用场景

    • 系统快照分析
    • 对象关系验证
    • 运行时分析

10. 通信图 (Communication Diagram)

  • 用途:展示对象间的消息传递
  • 展示内容

    • 对象关系
    • 消息传递
    • 交互顺序
    • 对象链接
  • 适用场景

    • 对象交互分析
    • 消息流设计
    • 系统行为分析

选择图表类型的考虑因素

  1. 要表达的内容(结构、行为、关系等)
  2. 目标受众(开发人员、业务人员、架构师等)
  3. 设计阶段(需求分析、架构设计、详细设计等)
  4. 具体场景(系统设计、业务流程、部署规划等)

项目建议

对于您的项目,建议使用:

  1. 类图展示领域模型
  2. 时序图展示业务流程
  3. 组件图展示系统架构
  4. 活动图展示复杂业务逻辑

参数root
当参数root为null时,attachToRoot参数无效。且生成的view会丢失布局文件中的LayoutParams
当参数root不为null时,生成的view会根据root类型来保留布局文件中对应的LayoutParams

参数attachToRoot
attachToRoot为true时,返回的view就是root
attachToRoot为false时,返回的view是跟布局生成的view

问题:一个viewpager2使用了FragmentStateAdapter,当系统配置发生变化(切换横竖屏、切换深色模式、切换语言),会多出fragment实例,每切一次就会多一次。查看日志每次切换后获取fragment的时候,都会重新走FragmentStateAdapter的createFragment。而之前已经生成的fragment都会重建。所以造成上面的现象和问题。

原因:这个viewpager2是动态通过代码new创建的,改成直接写在xml布局中就正常了(一般写在xml中都会加一个id的)

根因:只有绑定id的viewpager2才能正常同步fragment。从xml加载的也需要加id才能。代码动态创建的,设置id后也能正确。

private void ensureFragment(int position) {
    long itemId = getItemId(position);
    if (!mFragments.containsKey(itemId)) {
        // TODO(133419201): check if a Fragment provided here is a new Fragment
        Fragment newFragment = createFragment(position);
        newFragment.setInitialSavedState(mSavedStates.get(itemId));
        mFragments.put(itemId, newFragment);
    }
}

FragmentStateAdapter源码显示,只有mFragments不包含的时候,才会从createFragment拿

@Override
public final void restoreState(@NonNull Parcelable savedState) {
    if (!mSavedStates.isEmpty() || !mFragments.isEmpty()) {
        throw new IllegalStateException(
                "Expected the adapter to be 'fresh' while restoring state.");
    }

    Bundle bundle = (Bundle) savedState;
    if (bundle.getClassLoader() == null) {
        /** TODO(b/133752041): pass the class loader from {@link ViewPager2.SavedState } */
        bundle.setClassLoader(getClass().getClassLoader());
    }

    for (String key : bundle.keySet()) {
        if (isValidKey(key, KEY_PREFIX_FRAGMENT)) {
            long itemId = parseIdFromKey(key, KEY_PREFIX_FRAGMENT);
            Fragment fragment = mFragmentManager.getFragment(bundle, key);
            mFragments.put(itemId, fragment);
            continue;
        }

        if (isValidKey(key, KEY_PREFIX_STATE)) {
            long itemId = parseIdFromKey(key, KEY_PREFIX_STATE);
            Fragment.SavedState state = bundle.getParcelable(key);
            if (containsItem(itemId)) {
                mSavedStates.put(itemId, state);
            }
            continue;
        }

        throw new IllegalArgumentException("Unexpected key in savedState: " + key);
    }

    if (!mFragments.isEmpty()) {
        mHasStaleFragments = true;
        mIsInGracePeriod = true;
        gcFragments();
        scheduleGracePeriodEnd();
    }
}

然后可以看见除了ensureFragment,只有在restoreState这个地方mFragments才会存fragment。关键是要从savedState拿到fragment。

继续跟源码可以发现adapter的restoreState方法是在viewpager2的restorePendingState方法中被调用的,其中传递的参数是mPendingAdapterState,继续看看mPendingAdapterState哪儿来的

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (!(state instanceof SavedState)) {
        super.onRestoreInstanceState(state);
        return;
    }

    SavedState ss = (SavedState) state;
    super.onRestoreInstanceState(ss.getSuperState());
    mPendingCurrentItem = ss.mCurrentItem;
    mPendingAdapterState = ss.mAdapterState;
}

mPendingAdapterState来自于viewpager2的onRestoreInstanceState。

protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
    if (mID != NO_ID) {
        Parcelable state = container.get(mID);
        if (state != null) {
            // Log.i("View", "Restoreing #" + Integer.toHexString(mID)
            // + ": " + state);
            mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
            onRestoreInstanceState(state);
            if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
                throw new IllegalStateException(
                        "Derived class did not call super.onRestoreInstanceState()");
            }
        }
    }
}

可以看见只有当有id的时候才会执行onRestoreInstanceState

  1. 有需求在子进程中创建provider实例,需要添加android:multiprocess="true"或者直接指定android:process属性来指定进程
  2. 在主进程中,Provider 会在应用启动的时候自动初始化一次,创建实例,执行oncreate方法
  3. 系统不会自动在子进程中初始化 Provider,只有当子进程首次访问这个 Provider 时,系统才会在该进程中初始化一个新的 Provider 实例,只有创建实例时候才会执行oncreate方法
  4. 为了解决这个问题,可以主动初始化
public class ProviderUtils {
    public static void initializeProvider(Context context, ProviderInfo providerInfo) {
        try {
            // 通过 ContentResolver 触发 Provider 初始化
            Uri uri = Uri.parse("content://" + providerInfo.authority);
            ContentProviderClient client = context.getContentResolver()
                    .acquireContentProviderClient(uri);
            if (client != null) {
                // Provider 已初始化
                client.release();
            } else {
                // 尝试通过 call 方法触发初始化
                context.getContentResolver().call(
                    uri,
                    "init",
                    null,
                    null
                );
            }
        } catch (Exception e) {
            Log.e("ProviderUtils", "Failed to initialize provider: " + providerInfo.authority, e);
        }
    }

    // 初始化所有 Provider
    public static void initializeAllProviders(Context context) {
        List<ProviderInfo> providers = getAllProviders(context);
        for (ProviderInfo provider : providers) {
            initializeProvider(context, provider);
        }
    }
}

放在application oncreate或者其它合适的地方