当前位置:  编程技术>移动开发
本页文章导读:
    ▪某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException错误的解决办法        某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法在某APK中,通过如下方法动态注册了一个BroadcastReceiver,代码参考如下: @Override prot.........
    ▪ 遇到Audio/Speech相关有关问题,怎么抓取log        遇到Audio/Speech相关问题,如何抓取log [DESCRIPTION] 遇到Audio/Speech相关问题时,经常需要抓取相关log信息,总结抓取方法如下 [SOLUTION] 1.    通话声音相关的问题: Case 1: 通话中某一方或者双.........
    ▪ 产品经理的工作感触(4)       产品经理的工作感想(4)活下来的永远是少数 每个月来一次的,除了账单,还有那场“战争”。虽然活下来的永远是少数,但我越来越觉得,为了我们的产品,有些需求死得其所。 这是一.........

[1]某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException错误的解决办法
    来源: 互联网  发布时间: 2014-02-18
某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法

在某APK中,通过如下方法动态注册了一个BroadcastReceiver,代码参考如下:

    @Override
    protected void onAttachedToWindow()
    {
        super.onAttachedToWindow();
        
        /* monitor time ticks, time changed, timezone */
        
        if (mIntentReceiver == null)
        {
            mIntentReceiver = new TimeChangedReceiver(this);
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_TIME_TICK);
            filter.addAction(Intent.ACTION_TIME_CHANGED);
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
            getContext().registerReceiver(mIntentReceiver, filter);
Launcher要动态加载此APK(动态加载APK的目的和实现思路,参见我的这个文章:Launcher中动态加载其它APK中Activity的问题解决思路),

出现了如下异常:

09-05 19:05:55.033: E/AndroidRuntime(28637): java.lang.SecurityException: Given caller package com.zhao3546.time is not running in process ProcessRecord{41e74e50 28637:com.zhao3546.launcher/u0a10142}

搜索了一下,很多人遇到过此类问题,但都没有提出解决方法,看来只能自己动手解决了。

动态加载不行,那在AndroidManifest.xml试试静态加载BroadcastReceiver是否可以?

如果是其它的BroadcastRecevier,验证了是ok的,但android.content.Intent.ACTION_TIME_TICK这个不行,Android的注释中已经明确说明了。

String android.content.Intent.ACTION_TIME_TICK = "android.intent.action.TIME_TICK"

Broadcast Action: The current time has changed. Sent every minute. You can not receive this through components declared in manifests, only by exlicitly registering for it with Context.registerReceiver(). 

This is a protected intent that can only be sent by the system.

难道就真的没有解决方法了?

手头有一份Android源码,我根据“Given caller package”和“is not running in process ProcessRecord”这两个关键字全文搜索,

想看看抛出这个异常的代码是在哪里搞出来的,在*.cpp,*.c*,*.java中搜索都没有找到,先放弃此方法吧。

 

回头再来分析此异常,

09-05 19:05:55.033: E/AndroidRuntime(28637): java.lang.SecurityException: Given caller package com.zhao3546.time is not running in process ProcessRecord{41e74e50 28637:com.zhao3546.launcher/u0a10142}

我是在第三方APK中注册的BroadcastReceiver,这个APK在AndroidManifest.xml中声明的包名正好是“com.zhao3546.time”,而最终是和Launcher运行在同一个进程中的,这个进程对应的包名是“com.zhao3546.launcher”,因为Launcher先运行,而APK是被动态加载进来的。

那是不是只要我注册BroadcastReceiver对应的包名只要是“com.zhao3546.launcher”,就可以解决问题了?

Launcher中动态加载其它APK中Activity的问题解决思路,此文中已经通过将Launcher和第三方APK的AndroidManifest.xml中android:sharedUserId属性声明成为一致了,

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zhao3546.time"
    android:sharedUserId="zhao3546.launcher"

所以Launcher和第三方APK实际上是运行在同一个进程中的,那只要将Launcher的context对象传给这个APK,这个APK使用Launcher的context去注册BroadcastReceiver,是不是就可以解决问题了?

第三方APK的com.zhao3546.time包下新增如下类,并实现有public static void setContext(Context context)这个静态方法:

package com.zhao3546.time;

import android.content.Context;

public class ContextHolder
{
    private static Context context = null;
    
    public static void setContext(Context context)
    {
        System.out.println("com.zhao3546.time.ContextHolder setContext");
        
        ContextHolder.context = context;
    }
    
    public static Context getContext()
    {
        System.out.println("com.zhao3546.time.ContextHolder getContext() context="
                + context);
        
        return context;
    }
}

在Launcher代码中,通过反射机制动态地将launcher的context对象传到 com.zhao3546.time.ContextHolder 中,

    private void setContext2Plugin(ClassLoader pluginClassLoader,
            String pluginPackageName, Context launcherContext)
    {
        String className = pluginPackageName + ".ContextHolder";
        try
        {
            Method m = pluginClassLoader.loadClass(className)
                    .getMethod("setContext", Context.class);
            m.invoke(null, launcherContext);
        }
        catch (Exception e)
        {
            Log.w(TAG, "Fail to loadClass " + className + ", skip it", e);
        }
    }

修改之前注册BroadcastReceiver的地方,通过ContextHolder()来注册BroadcastReceiver,把APK重新部署验证,问题解决。

 

看似解决不了的问题,其实有时需要换个思路去尝试不同的方法,可能就会取得意想不到的效果。



    
[2] 遇到Audio/Speech相关有关问题,怎么抓取log
    来源: 互联网  发布时间: 2014-02-18
遇到Audio/Speech相关问题,如何抓取log
[DESCRIPTION]
遇到Audio/Speech相关问题时,经常需要抓取相关log信息,总结抓取方法如下
[SOLUTION]
1.    通话声音相关的问题:
Case 1: 通话中某一方或者双方都无声音,所需Log:VM Log ;Register info ; Mobile Log ;Modem Log
Case 2: 输出设备routing 错误:Mobile Log;Register info
2.    音乐播放声音相关问题:
Case 1: 某一设备没有声音输出,所需Log: Register info ; Mobile Log
Case 2: 声音卡顿问题, 所需Log:Mobile Log ;ftrace ;PCM data
Case 3:杂音,噪音问题,所需Log:Mobile Log;PCM data
3.    FM声音相关问题:
Common:需要请客户提供FM chip的型号,连接方式(Analog or I2S)
Case 1: 某一设备没有声音输出,所需Log: Register info ; Mobile Log

工模中没有开启mobile log选项,可使用logcat抓取mobile log:
Ex. 
# for the main log
adb wait-for-device logcat -v time > dt_XXX_main_20120727.txt 2>&1
# for the radio log
adb wait-for-device logcat -v time -b radio > dt_XXX_radio_20120727.txt 2>&1

VM Log 抓取方法:
1.    插入sdcard,用来存储所谓的vm log;
2.    进入Engineer Mode;
3.    Enter Engineer Mode\Audio\Speech Enhancement\common parameter的parameter 0设置为6;如果是debug DMNR的话,此处需要设定为13;特别要看AEC的话,要设定成7;
4.    Enter Engineer Mode\Audio\Debug Info\Parameter 0设置为 3;
5.    Enter Engineer Mode\Audio\Speech Logger\单击 Enable.
6.    退出Engineer Mode.
7.    拨打一个电话,或者接听一个电话,通话过程中复现贵司所说的问题。
8.    挂断电话,并将/sdcard/speechlog下的*.vm文档寄过来即可。
After MT6577 VM Log抓取办法:
1.    插入sdcard,用来存储所谓的vm log;
2.    进入Engineer Mode;
3.    Enter Engineer Mode\Audio\Speech Logger\单击 Enable,并选择Enable EPL.
4.    退出Engineer Mode.
5.    拨打一个电话,或者接听一个电话,通话过程中复现贵司所说的问题。
6.    挂断电话,并将/sdcard/VM_Log下的*.vm文档寄过来即可。

Register info抓取方法:
1.    复现问题
2.    从命令行中进入adb shell mode
3.    输入 cat proc/audio
4.    截取register info并保存到txt中
Tips:概率性问题,需要在正常和复现问题时各抓取一次
After MT6577 Register info抓取办法:
1.    打开mobile log中的kernal log
2.    进入工模->Audio->Audio Logger,点击dump audio debug info
3.    将kernal log发给我们即可
Tips:概率性问题,需要在正常和复现问题时各抓取一次

PCM data 抓取方法:
1.    插入sdcard,用来保存PCM data
2.    复现问题
3.    在命令行中输入adb shell setprop streamout.pcm.dump 1
4.    抓取结束后,在命令行输入adb shell setprop streamout.pcm.dump 0还原设定
5.    将sdcard中生成的.pcm文件寄过来即可
After MT6577 PCM Data Dump方法:
1.    插入sdcard,用来保存PCM data
2.    进入工模->Audio->Audio Logger,点选需要抓取的pcm data
3.    复现问题,抓取data dump,再进入工模点掉刚才的选项
5.    将sdcard中生成的.pcm文件寄过来即可
 
Tips:针对PCM Data,我们有很多点可以抓取,对应的Property是不一样的(MT6577以后的平台,只需要点选对应的选项即可)
如果是播放问题,我们需要stream out的pcm data,各点对应的Property如下:
af.track.pcm;af.mixer.pcm;streamout_ori.pcm.dump;streamout.pcm.dump;a2dp.streamout.pcm
 
如果是录音相关问题,我们需要dump stream in的pcm data,各点对应的property如下:
I2S.streamin.pcm;streamin.pcm.dump;af.record.dump.pcm
具体可参考AudioYusuStreamOut.cpp,AudioYusuStreamIn.cpp中对Property的定义.

ftrace:
1.    复现问题
2.    运行ftrace tool下的start_ftrace_short.bat开始
3.  运行ftrace tool下的stop_ftrace_short.bat停止
4.  将抓取到的.vcd文件提供给我们分析
After MT6577 Dump Ftrace方法:
连接ADB,turn OFF and then turn ON:
adb shell setprop dumpftrace_dbg  0
adb shell setprop dumpftrace_dbg  1

How to get Modem log:
针对Audio这个模块来讲,需要设定filter为:MOD_L1SP all classes on.

【[Catcher 3.1133.00]后的Cather来导出“catcher_filter.bin”,可以跳过第1,2两步】 
1:在Cather里的filter設置好后,將filter導出來,生成一個“filter.ini”,這個名字可以自己命名。 
Filter里設置好需要抓取log的filter,點“Export”按提示操作 
 
 
 
2:用Cather工具目錄里的工具log2sdFltrGen.exe將第3步生成的ini文件轉為名稱為“catcher_filter.bin”的文件,請注意必須按這個文件名! 
使用這個工具,“Browse DB”選擇database,“Browse INI”選擇第3步生成的ini文件, 
點“Generate BIN”,然后按提示將生成文件命名為“catcher_filter.bin” 
 
 
3:使用[Catcher 3.1133.00]后的Cather来导出“catcher_filter.bin” 
You can export filter setting to catcher_filter.bin from Catcher directly without using log2sdFltrGen.exe. In Filter dialog, press “Export” button and then select “Export to *.bin” to enable this feature. 
 
4:將“catcher_filter.bin”文件拷貝到T卡的mtklog\mdlog目录下 
 
 
5:进入工程模式->systemlog->modem log->选择存储到T卡,就會有*.dmp的log文件生成,這個文件很小,因為存的是log的簡化信息,需要用catcher和database來還原信息 
 
6:將”*.dmp”文件從T里拷貝出來,用catcher和database來還原信息 
Controls->Open dump file 
 
本例中設定的MOD_BMT log,還原如下: 
 



    
[3] 产品经理的工作感触(4)
    来源: 互联网  发布时间: 2014-02-18
产品经理的工作感想(4)

活下来的永远是少数

每个月来一次的,除了账单,还有那场“战争”。虽然活下来的永远是少数,但我越来越觉得,为了我们的产品,有些需求死得其所。

这是一场公司内部的战争,每个产品的产品经理都要上场,打仗总是为了抢点什么,我们争夺的是下个月的人力资源,即总是不够用的开发工程师、测试工程师等。战场就是闻之色变的产品会议,而我们手上的武器,则是精心准备的商业需求文档。这个过程,就是需求筛选,如图2-16所示,也有个很传神的说法:需求PK。

 

准备出发:把需求打个包

上战场之前,就像战士要把自己的物品打包一样,需求也要打包。我们现在来解决这个包有多大的问题,即某个将来的潜在项目里,到底应该包括多少需求的问题。这里不得不提前谈一点项目管理的内容了。

做项目,终极目标就是:多快好省19

但又要马儿跑又想马儿不吃草的事情是没有的,所以我们通常是在上述4 个要求中做平衡。我经历的互联网、软件项目,比较推崇敏捷方法,即范围大、时间短、品质高、资源省。

,所以有比较固定的项目时间,专业点叫“迭代周期”,一般是2~4 周。然后有一个人员相对固定的团队,意味着项目资源确定,此外任何时候都要保证项目品质,最后能变的只能是量——项

目范围。继续,我们有了项目时间长短,也就意味着可以按经验的比例估计出留给开发的

时间有几天,然后团队里有多少开发工程师也是知道的,所以我们可以直接算出有多少“可用工作量”同样以“人天”为单位。还记得我们把产品需求列表按照“性价比”从大到小排序过了么?从上往下看,每一行后面都还对应着一个“工作量”,现在我们只要做一个简单的加法,一行又一行地从上到下依次纳入项目,能做多少,一目了然,我们把这个动作叫“需求打包”,而对这些需求的整体描述,也就是商业需求文档里的功能说明了。

当然,这只是一个基准,可变因素很多。我们每次产品会议都要准备好几个项目让大老板们选,每个项目也有可能在产品会议上被砍掉部分需求,所以可以先相对随意地超出“可用工作量”。

这个过程完全定量地回答了“做多少”的问题。但,真实情况哪会这么简单明了,就像课本里总是给出一个简单到不真实的例子,然后再告诉你还有很多特例,而到了实际操作中,你会发现又要复杂很多,没办法,大家都尽力吧,让每个项目的大小相对靠谱,下面说几个需要注意的地方。

 

第一,“需求打包”最好打包类似的功能点。

是否类似取决于需求的基本属性,这是“确定需求的基本属性”那一节里做的事情。一般来说业务上逻辑关系密切的需求才会包含在一个项目里,这也很好理解,否则就是一个纯粹修修补补的“小需求项目”了。实际操作中打包多大,更多的是取决于这一点。更好的方式是,需求在打包以后,通过业务逻辑图的方式可视化,可以更直观地给别人讲解

如图 2-17 所示,是我在2009年春做的一个项目的业务逻辑图,因为涉及一些商

业问题,所以图中有些关键词隐去了。

图 2-17 魔方计划的业务逻辑图

第一, 需求依赖,功能互相之间有依赖关系。

那些只能先做的功能,应该在产品需求列表里注明;功能与人力资源之间的依赖关系也常在比如有些功能只能由团队里的特定成员来做。在这里评估工作量的时候不会考虑“谁来做的问题,在正式立项以后,组建团队的时候会重点考虑,当然长期来说,为了避免这类风险,提升与平衡团队成员的能力是王道。

第二, 需求的粒度大小问题。商业价值很高的功能,如果细分的话,我们会发现其中也有价值相对低的部分,所以需求的粒度应该尽量细,前提是细化引起的管理成本上升在可接受的范围内,给个生活中的例子帮助理解:大开间办公区域里的灯,不可能用一个开关控制,也不可能每一个开关只控制一盏灯。具体细到多少,要根据具体情况具体分析。我们的经验是,在需求列表里出现的任意一行,工作量最好不要超过“5 人天”。

 

战场:产品会议

需求打包完成了,战争就要打响了。

某天,各个部门的老板们都聚集到一个大会议室,准备待上一整天。各个产品的产品经理和设计师们等着被轮流召唤,当然如果你有空且愿意,也可以旁听一整天。其实对资源的争夺,在部门内讨论商业价值的时候已经预演过了,通常来说每个人都会尽力为自己提出的需求说好话,毕竟实现自己想法的感觉总是好过帮别人实现想法。一般来说产品会议一个月一次,当然这和产品性质有关,如果你们公司的产品周期比较长,那也可以两三个月一次。

当某个产品团队开始登场亮相的时候,一般要先回顾上一次产品会议通过的项目,现在进展如何,是否需要调整时间进度、是否需要追加资源、是否有重大需求变更,已经发布的项目有什么问题,等等。这样一方面是为了让大老板们更新对各个项目的信息,更重要的是为了积累经验,让今后产品会议上的决策越来越合理。

回顾之后,就是最关键的部分了,我们会拿出准备好的商业需求文档,每个产品都会拿出三五个,占满2~3 倍的潜在资源。这里说的潜在资源,是指相对固定的开发、测试人员,因为技术人员有对产品的熟悉问题,所以在短时间内,不可能太多的人同时转去做其他产品,这也就意味着潜在的力资源数量是在一个值附近做微小浮动的,所以我们也可以认为,在一定程度上,资源的争夺是以产品间的争夺为辅,产品内多个项目的争夺为主。很有意思的是,这三五个商业需求文档通常是产品团队里不同的人做出来的,所以内部也会争夺得你死我活

接下来的重头戏是一直提到的商业需求文档。

 

 

武器:商业需求文档

我们刚刚把需求打好包,接下来就要描述一下这个包了,这就是商业需求文档,BusinessRequirement Document,简称BRD,它也是我们参加资源争夺战的武器。

先看一下几个长得很像的词:BRD、MRD21、PRD22

21 MRD:Market RequirementDocument,市场需求文档。

22 PRD:ProductRequirements Document,产品需求文档,在本书第3.3.1 节的“产品需求文档,PRD”里有详细讲述。

。按顺序来讲,这几个词是从商业的描述渐渐过渡到对技术的描述。我经历的团队在实际操作中通常只写两种文档,一个是给大老板们看的BRD,包含了BRD,以及MRD的部分内容;另一个是在项目中

写的PRD。

下面来聊聊我们的武器——BRD 怎么写,都包含哪些内容。

项目背景:我们在哪里?为什么要做这个项目,解决什么问题,可以列出一些数据说明项目的必要性。

商业价值:我们去哪里?最关键的重点!大老板们最感兴趣的,做了这个项目以后有什么价值,一定要说在点子上。一般我们还会预测一下相关数字的变化,提出这个项目的商业目标。

功能需求描述:我们怎么去?通过做哪些事情来达到目标,把打好包的需求描述一下,可以用功能列表的形式表达,但最好能画出业务逻辑关系。当然我们也经常会搞点技巧性的东西,比如故意加入一些让老板砍的需求,希望老板砍完之后心有愧疚不好意思再砍我们真正想做的东西,这有点类似谈判技巧里的玩意,大家可以试试,但不要在这上面太花心思了。

非功能需求描述:提一下重要的非功能需求,如果有的话。

资源评估:第二个重点!大老板们要看成本,他们在了解达成项目的目标需要多大的花费以后,才能做出决策。

风险和对策:有的项目会有一些潜在风险,这个时候不妨抛给老板们看一下,并且给出自己的对策,说不定你觉得是很大的麻烦,在老板那里一句话就可以搞定。而且由于信息的不对称,我们无法了解某些功能是否会与公司将来的战略冲突,这时候提出来也是让老板们把一下关。从BRD 中的“商业价值”、“资源评估”两个重点中大家可能也发现了,其实本质上大老板们也是在追求那个词——性价比。大家都希望花费最少的资源获得最大的商业价值。

 

别灰心,少做就是多做

有100 个需求,资源只够做10 个,是的,当时就是这样。

一直都是这样。

网店版“自动上架”的功能,简单解释一下:

淘宝为了防止一些没人打理的商品始终在搜索结果中,稀释了有效信息,所以所有商品会隔一段时间后自动下架,不再被搜索到,这时就需要用户重新将商品上架。而网店版的用户都是淘宝的优质卖家,所以我们给他们提供了一个“自动上架”的功能。这是一个确定“怎么做”的过程,当时的体会能很好地表达我的想法,借用一下。两个礼拜,整天的PK、评审、确认,搞得头昏脑胀,不过终于算是把需求定下来了。一个功能的多次需求会议中,必然有这样一个过程:开始对一个功能想得不完整,说着说着大家都想把这个功能做得再强一点,这里加一点那里加一点,但后来通常因为技术实现、资源等原因,又把这些加上去的功能点一个又一个地砍掉,甚至会发现砍到最后和一个月前的第一次方案是一样的。看似白搭的这个过程其实是有用的,这是一个“见山是山,见山不是山,见山还是山”的三段过程,对于那些加上又砍掉的功能点,在第一个阶段我们根本没有想到,第二个阶段想到了,很兴奋,那就做吧,而第三个阶段的砍掉是权衡了利弊之后的决定,和“没想到”是完全不同的。我们无法绕过第一阶段的无知,也千万别停在中间那个功能点“大而全”的时候,必死无疑!而第三阶段的“少做”则是超越第二阶段“多做”的“少做”,这才是真正的“多做”。

有很多文章谈到这样的思想,用100%的质量去实现75%的数量,而不是反过来!吸引用户的往往只是功能模块中的一两个点,我们一开始只要让其拥有100%的质量其实就够了,这样留给用户的是升级的期待,而如果反过来,功能铺得很开,但每个点都不爽,那反而喧宾夺主,把闪光的地方给掩埋了。

情愿把一半的功能做到尽可能完美也不要把全部功能都做成半吊子。越来越觉得

当发现一个功能可有可无的时候,甚至只要是没有强烈的理由要做的时候,要明确的

选择:不做!现在我们可以自我安慰了——少做就是多做!



最爽就是“四两拨千斤”

做得少不如做得巧。

第 2.3.1节中我们提到满足需求有三种方式,其实就算“改变现状”这样一种最常

用的办法,也有很多“四两拨千斤”的方案。如果机会闪现,就千万不要放过,因为做这样的事情实在太爽了,让我对下面这个故事过目不忘。

话说某跨国日化公司,肥皂生产线上面存在包装时可能漏包肥皂的问题。

于是该公司总裁命令组成了以博士牵头的专家组对这个问题进行攻关。该研发团队使用了世界上最高精尖的技术(如红外探测、激光照射等),在花费了大量美金和半年的时间后终于完成了肥皂盒检测系统,探测到空的肥皂盒以后,机械手会将空盒推出去。这一办法将肥皂盒空填率有效降低至5%以内。

问题基本解决。

再说某乡镇肥皂企业也遇到类似问题,老板命令初中毕业的流水线工头想办法解决之,经过半天的思考,该工头拿了一台电扇到生产线的末端对着传送带猛吹,那些没有装填肥皂的肥皂盒由于重量轻就都被风吹下去了。

这样做得更少,但是效果更好,至少性价比更高。当然,具体情况要具体分析,任何事情总有它的两面,上例中乡镇企业的换到跨国公司的环境中,也许并不适用,比如会造成肥皂盒无规律地四处翻滚,引起更大的问题,但我想表达的意思是:

我们用不着觉得只有“吃苦耐劳”,做了很多事情才是贡献,而应该直接从目的出发。有一句话说得好:内部(指偏技术)的大改动往往是外部(指偏商业)的小改动,反之亦然,所以我们应该在动手前先找找有没有成本低,收效大的!



尽可能多地放弃

我说“尽可能多地采集”,这里,我又说“尽可能多地放弃”,看似矛盾,其实正反映了我们对事物的认识过程,只有在收集阶段没有遗漏,才可能完整地看到事物的全貌,有了大局观,在放弃的时候才知道孰重孰轻,也更下得了手。

多年以前我看到白鸦23

23 白鸦,支付宝产品设计师,UCDChina 发起人,5G 咨询合伙人,专注于以用户为中心的互联网产品设计的Blogger。

个人博客uicom.net。

写过的一段例子,发现如果不放弃,最终会被自己折腾死,

他是这么说的:

比如,一个最简单的“评论”功能:既然可以发评论,那么……

是不是需要改评论?

删评论?

发的权限是否要管理员设置?

人人都是产品经理

90

那么改的权限呢?

删的权限呢?

是否可以引用别人的评论?

评论被人引用了是否可以再改?

如果可以改那么是不是要保留修改记录?

如果管理员改了一个评论那么作者是不是不能再改?

评论是否要有数量和时间限制?

评论要不要翻页?

如果要翻页是在本页翻还是打开新页?

评论能不能带图片?

带了图片那么是不是能上传?

能上传之后是不是要删除?

是不是要提供自定义评论排序?

是不是要xx?

是不是 xx?

xx?

……

“需求越来越多,让人崩溃,但是要做的事情太少,似乎也会有问题。”小明忍不

住跳出来问。

小明:“有资源空出来了怎么办?”

大毛:“要做的数量是少了,但要达到100%的质量,一般很难空出资源。”

小明:“真的空出来了怎么办?”

大毛:“去找其他意义更大的功能。”

小明:“找不到怎么办?”

大毛:“把空闲下来的人拉去做另外一个意义重大的产品,这不可能再找不到了。”

“少做就是多做”,阿里巴巴的马云也说过。

 


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
建站其它 iis7站长之家
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3