铃声设置的流程

Android系统铃声设置的流程

Sound & notification
–> General —> Phone ringtone
Default notification sound


单卡情况下:

直接跳到RingtonePickerActivity这个list列表,进行选择铃声的操作。

双卡情况下:

调到选择sub sim卡的界面,待选择完sim卡,然后载调到RingtonePickerActivity这个list列表,进行选择铃声的操作。

到底是怎么跳转到RingtonePickerActvity界面的,因为在EditProfile界面并未看到任何显示或者隐式打开RingtonePickerActivity的入口。

以ringtone的设置为例:

private void initRingtone(PreferenceScreen parent) {
    //这里看到,找控件,也就是Phone ringtone这个preference,可以看出其实际为 DefaultRingtonePreference 
    mVoiceRingtone = (DefaultRingtonePreference) parent.findPreference(KEY_RINGTONE);
    mVideoRingtone = (DefaultRingtonePreference) parent.findPreference(KEY_VIDEO_RINGTONE);
    mSipRingtone = (DefaultRingtonePreference) parent.findPreference(KEY_SIP_RINGTONE);
}
在EditProfile中找不到跳转的入口,那就进入DefaultRingtonePreference去看下有没有,但是仍然找不到,只能找到onPrepareRingtonePickerIntent方法,看着像,但是并未有哪里执行了startActvity啊。
public class DefaultRingtonePreference extends RingtonePreference {。。。。}
   那可以看到DefaultRingtonePreference 的父类为RingtonePreference ,所以可以看下,是不是在父类中有相应的解释,追踪到
frameworks/base/core/java/android/preference/RingtonePreference.java

果然找到了,父类内部实现了onclick事件,并且在其中调用onPrepareRingtonePickerIntent方法,将其中初始化的intent同样作为参数,start出去。现在就一目了然了。

@Override
protected void onClick() {
    // Launch the ringtone picker 那就是这里了,隐式得跳转,通过action
    Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
    onPrepareRingtonePickerIntent(intent);
    PreferenceFragment owningFragment = getPreferenceManager().getFragment();
    if (owningFragment != null) {
        owningFragment.startActivityForResult(intent, mRequestCode);
    } else {
        getPreferenceManager().getActivity().startActivityForResult(intent, mRequestCode);
    }
}

而且可以发现,其是以startActvityForResult的方式来跳转,那么必然有onActivityResult方法。

public boolean onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == mRequestCode) {

            if (data != null) {
                Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);

                if (callChangeListener(uri != null ? uri.toString() : "")) {
                    //这里会调用onSaveRingtone方法
                    onSaveRingtone(uri);
                }
            }

            return true;
        }

        return false;
    }

正好可以对应到,在ringtonePicker列表中选择完毕铃声后,返回后设置了铃声的动作,这里在其子类DefaultRingtonePreference中完成了重写。

/**
     * Called when the ringtone is choosen, set the selected ringtone uri to framework
     *
     * @param ringtoneUri
     * the selected ringtone uri
     */
    @Override
    protected void onSaveRingtone(Uri ringtoneUri) {
  //xxw
  int simNum = SubscriptionManager.from(getContext()).getActiveSubscriptionInfoCount();
  if(simNum == 0){
   Toast.makeText(mContext, mContext.getString(R.string.no_sim_card_tip), 2000).show();
  }else {//xxw .
        SharedPreferences prefs = this.getContext().getSharedPreferences(
                "DefaultRingtonePreference", Context.MODE_PRIVATE);
        mSimId = prefs.getLong(PREF_SIM_ID_VALUME, -1);
        mProfileManager.setRingtoneUri(mKey, getRingtoneType(), mSimId, ringtoneUri);
        Log.d("kiki","onSaveRingtone ringtoneUri="+ringtoneUri.toString());
  }//xxw
    }
<think>好的,用户想学习Transformer模型,我需要根据提供的引用内容来构建一个结构清晰的回答。首先,要确保回答符合系统级指令,比如正确使用数学格式和引用标识。用户提到了几个引用,我需要从中提取相关信息。 首先,用户可能对Transformer的基本结构不太了解,需要从基础讲起。引用[2]和[3]提到了Transformer结构,特别是自注意力机制和多头注意力,这部分应该放在前面。然后,引用[4]解释了查询、键、值向量的生成,这部分可以作为自注意力的具体实现细节。 接下来,用户可能需要学习路径的建议。我应该分步骤,比如先理解基础概念,再学习数学原理,然后实战应用。引用[1]提到BERT、GPT等模型,可以作为进阶学习的例子,说明Transformer的应用广泛。 数学部分要注意使用$$...$$格式,比如自注意力公式。同时要确保代码示例正确,可能引用[3]的实战部分,但用户提供的引用中没有具体代码,可能需要避免假设,或者建议参考相关教程。 用户的问题还可能涉及如何应用Transformer到不同领域,比如NLP和CV,引用[1]提到ViT和Swin Transformer,可以在这里举例说明。 最后,生成的相关问题需要与学习Transformer相关,比如数学基础、多头注意力的作用、与RNN的对比、应用场景和优化方法。这些问题应基于回答内容,帮助用户深入理解。 需要检查引用是否正确添加,比如引用[3]提到Transformer结构行性优势,引用[4]解释QKV向量。确保每个引用标识自然放置在相关段落末尾。 可能用户是初学者,所以步骤要详细,从基础到进阶,理论加实践。同时,要推荐学习资源,如论文和实战教程,引用提供的资料可以作为推荐的一部分。 总结回答结构:基础概念、核心结构、数学原理、学习路径、实战建议、应用领域,最后相关问题。这样逐步引导用户,确保逻辑清晰,引用正确,符合用户需求。</think>### 分步学习Transformer模型的指南 #### 1. **基础概念理解** - **自注意力机制**是Transformer的核心创新,通过计算输入序列中每个词与其他词的关系权重,实现全局依赖性建模。例如,句子中的"it"可能通过注意力机制关联到前文的关键名词[^4]。 - **行计算优势**:相比RNN的序列处理,Transformer行计算所有位置的注意力权重,大幅提升训练效率[^3]。 #### 2. **核心结构解析(附数学原理)** 完整Transformer结构包含编码器(Encoder)和解码器(Decoder),以下为编码器的数学表达: $$ \text{MultiHead}(Q,K,V) = \text{Concat}(\text{head}_1,...,\text{head}_h)W^O \\ \text{其中} \ \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) $$ 式中$W_i^Q, W_i^K, W_i^V$为参数矩阵,$h$代表注意力头数量[^2][^4]。 #### 3. **学习路径建议** 1. **前置知识** - 掌握矩阵运算($softmax$, 矩阵乘法) - 理解词嵌入(Word Embedding)技术 - 熟悉残差连接与层归一化 2. **关键论文研读** - 精读《Attention Is All You Need》原文(含完整架构图) - 延伸阅读BERT、GPT论文,理解变体差异[^1] 3. **代码实践阶段** ```python # 自注意力简化实现(PyTorch示例) import torch.nn as nn class SelfAttention(nn.Module): def __init__(self, embed_size, heads): super().__init__() self.embed_size = embed_size self.heads = heads self.head_dim = embed_size // heads self.values = nn.Linear(self.head_dim, self.head_dim, bias=False) self.keys = nn.Linear(self.head_dim, self.head_dim, bias=False) self.queries = nn.Linear(self.head_dim, self.head_dim, bias=False) self.fc_out = nn.Linear(heads * self.head_dim, embed_size) ``` #### 4. **应用领域扩展** - **跨模态应用**:CLIP模型将Transformer应用于图文匹配[^1] - **计算机视觉**:ViT(Vision Transformer)将图像分块处理为序列[^1] - **工业级优化**:研究模型压缩技术如知识蒸馏、量化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值