‘壹’ 如何从技术上全面分析一款android app
一、用户体验是王道
1.这是一个看脸的时代,不论是人还是app。
2.Android出现也已经是很长的一段时间了,各种技术相对比较成熟,开源社区里那些图片库、网络库、UI界面、数据框架一抓一大把,在同一个类别的应用中,如果没点干货真的很难脱颖而出。谁来判断干货,不是研发,不是pm,是用户。
3.我现在的Leader之前跟我说过一句话,我深以为然--做一款app,其实最核心的是怎么获取到用户,怎么愿意让用户去使用你,而不是你应用内的技术怎么怎么牛B。不喜勿喷,其实我刚开始的时候也不能理解,但是后来逐渐领悟到他说的竟然是对的。对于移动互联网来说,app的生生死死真是太常见了,各个公司每年新开的项目一大片,真正能够活下来的又有几个。所以在应用的前期还是努力迭代功能,让自己的app活下去之后,再考虑技术的问题吧
二、应用架构是否合理
1.简单就一句话,不要重复造轮子,不要重复造轮子,尤其是不要在一个应用里反复造多个轮子。现在的软件开发早就过了单枪匹马闯天下的时代了,很多个研发同时工作,难免会造成各自代码不熟悉,这时候就需要有人能够将整个应用的架构能够捋清楚,千万不要出现项目中我用我的库方法,你用你的库方法,大家一起造轮子玩这种情况。
2.能够使用开源库就从了他吧。还是那句话,别人造好的轮子,为嘛不用,非得自己造一个,真以为自己是全能吗?你不累我看着都累啊。
三、内存、网络、界面性能响应优化
其实大家都说过了软件性能的重要性,我在这里也就不再进行复述了,反正LeakCanary,TraceView等等性能工具,谁用谁知道。
四、单元测试
感觉国内好像很少有研发自己写单元测试的情况啊,其实我觉得很多时候,研发才是对功能最熟悉的人,很多边界条件只有在代码中才能够恰好遇到,所以写好单元测试做一只不麻烦QA的猿才是好猿。
五、安全
Sorry,我对应用安全不是很懂,就是简单用用Proguard混淆就Over了,加壳什么的感觉貌似没有太大必要,毕竟对于很多Android应用而言,其实看一眼大概知道他的界面逻辑了,ui层自己重写绝对比逆向快,而api接口之类的东西,或许是我不太敏感吧。
‘贰’ android 滚轮选择控件有哪些框架
android 滚轮选择控件是ios独有的一个控件,android还没有原生的,不过网上有一个仿照小米的滚轮字的字的自定义view,你可以到csdn下载频道搜搜看,是我上传的
‘叁’ android 时间滚轮怎么把选择的每个选项合并后转换成时间戳
1、添加compile:(这个库里用到了fastjson)
compile 'cn.qqtheme.framework:WheelPicker:1.2.3'
compile 'com.alibaba:fastjson:1.2.18'1212
2、assets文件夹下添加city.json,如下图:
3、代码中使用:
/**
* 地区选择器
*/
private void showRegionPicker() {
try {
final ArrayList<AddressPicker.Province> data = new ArrayList<>();
String json = ConvertUtils.toString(getAssets().open("city.json"));
data.addAll(JSON.parseArray(json, AddressPicker.Province.class));
final AddressPicker picker
‘肆’ 安卓手机如何在浏览网页时实现鼠标滚轮的功能
方法步骤(以UC浏览器为例)
一、打开浏览器,点下面的“三”形图标。
.
‘伍’ android app自动化测试工具有哪些
1、Monkey是Android SDK自带的测试工具,在测试过程中会向系统发送伪随机的用户事件流,如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试,也有日志输出。实际上该工具只能做程序做一些压力测试,由于测试事件和数据都是随机的,不能自定义,所以有很大的局限性。
2、MonkeyRunner也是Android SDK提供的测试工具。严格意义上来说MonkeyRunner其实是一个Api工具包,比Monkey强大,可以编写测试脚本来自定义数据、事件。缺点是脚本用Python来写,对测试人员来说要求较高,有比较大的学习成本。
3、Instrumentation是早期Google提供的Android自动化测试工具类,虽然在那时候JUnit也可以对Android进行测试,但是Instrumentation允许你对应用程序做更为复杂的测试,甚至是框架层面的。通过Instrumentation你可以模拟按键按下、抬起、屏幕点击、滚动等事件。Instrumentation是通过将主程序和测试程序运行在同一个进程来实现这些功能,你可以把Instrumentation看成一个类似Activity或者Service并且不带界面的组件,在程序运行期间监控你的主程序。缺点是对测试人员来说编写代码能力要求较高,需要对Android相关知识有一定了解,还需要配置AndroidManifest.xml文件,不能跨多个App。
4、UiAutomator也是Android提供的自动化测试框架,基本上支持所有的Android事件操作,对比Instrumentation它不需要测试人员了解代码实现细节(可以用UiAutomatorviewer抓去App页面上的控件属性而不看源码)。基于Java,测试代码结构简单、编写容易、学习成本,一次编译,所有设备或模拟器都能运行测试,能跨App(比如:很多App有选择相册、打开相机拍照,这就是跨App测试)。缺点是只支持SDK 16(Android 4.1)及以上,不支持Hybird App、WebApp。
5、Espresso是Google的开源自动化测试框架。相对于Robotium和UIAutomator,它的特点是规模更小、更简洁,API更加精确,编写测试代码简单,容易快速上手。因为是基于Instrumentation的,所以不能跨App。配合Android Studio来编写测试的简单例子
6、Selendroid:也是基于Instrumentation的测试框架,可以测试Native App、Hybird App、Web App,但是网上资料较少,社区活跃度也不大。
7、Robotium也是基于Instrumentation的测试框架,目前国内外用的比较多,资料比较多,社区也比较活跃。缺点是对测试人员来说要有一定的Java基础,了解Android基本组件,不能跨App。
8、Athrun是淘宝出的一个移动测试框架/平台,同时支持iOS和Android。Android部分也是基于Instrumentation,在Android原有的类基础上进行了扩展,提供一整套面向对象的API。这里有详细介绍。
9、Appium是最近比较热门的框架,社区也很活跃。这个框架应该是是功能最强大的,
它的优点:
开源;
支持Native App、Hybird App、Web App;
支持Android、iOS、Firefox OS;
Server也是跨平台的,你可以使用Mac OS X、Windows或者Linux;
它的哲理是:
用Appium自动化测试不需要重新编译App;
支持很多语言来编写测试脚本,Java、Javascript、PHP、Python、C#、Ruby等主流语言;
不需要为了自动化测试来重造轮子,因为扩展了WebDriver。(WebDriver是测试WebApps的一种简单、快速的自动化测试框架,所以有Web自动化测试经验的测试人员可以直接上手);
移动端自动化测试应该是开源的;
它的设计理念:
Client/Server架构,运行的时候Server端会监听Client端发过来的命令,翻译这些命令发送给移动设备或模拟器,然后移动设备或模拟器做出响应的反应。正是因为这种架构,所以Client可以使用Appium client libraries多种语言的测试脚本,而且Server端完全可以部署在服务器上,甚至云服务器。
Session,每个Client连接到Server以后都会有一个Session ID,而且Client发送命令到Server端都需要这个Session ID,因为这个seesion id代表了你所打开的浏览器或者是移动设备的模拟器。所以你甚至可以打开N个Session,同时测试不同的设备或模拟器。
Desired Capabilities,其实就是一个键值对,设置一些测试的相关信息来告诉Server端,我们需要测试iOS、还是Android,或者换是WebApp等信息。
Appium Server是Node.js写的,所以可以直接用NPM来进行安装。
Appium Clients,Mac OS和Win下提供GUI,不需要装Node.js,方便测试人员操作。
相关限制:
如果你在Windows使用Appium,你没法使用预编译专用于OS X的.app文件,因为Appium依赖OS X专用的库来支持iOS测试,所以在Windows平台你不能测试iOS Apps。这意味着你只能通过在Mac上来运行iOS测试。
总结:
在iOS部分是封装了UIAutomation;Android 4.2以上是用UiAutomator,Android 2.3 ~ 4.1用的是 Instrumentation,也就说Appium同时封装了UiAutomator和Instrumentation。所以Appium拥有了以上几大框架的所有优点:跨App,支持Native App、Hybird App、Web App,还支持N种语言来编写你的测试脚本。
‘陆’ Android 时间滚动轮 选择日期的范围
可以
xml设置:
<DatePicker
android:id="@+id/dp_date"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:calendarViewShown="false"
android:minDate="mm/dd/yyyy"
android:maxDate="mm/dd/yyyy"
/>
mm/dd/yyyy为 月/日/年 如 01/01/2014
或者在代码中设置:
...
datePicker = (DatePicker)findViewById(R.id.dp_date);
//设置开始日期
//从今天开始
Calendar startCalendar = Calendar.getInstance();
startCalendar.set(Calendar.HOUR, 0);
startCalendar.set(Calendar.SECOND, 0);
startCalendar.set(Calendar.MINUTE, 0);
startCalendar.set(Calendar.MILLISECOND, 0);
datePicker.setMinDate(startCalendar.getTimeInMillis());
//设置结束日期
//到280天后结束
Calendar endCalendar = Calendar.getInstance();
endCalendar.set(Calendar.DATE, startCalendar.get(Calendar.DATE) + 280);
long endDate = endCalendar.getTimeInMillis();
datePicker.setMaxDate(endDate);
...
‘柒’ android 轮子是什么意思
按↓
按↑会压轮子
有个技巧,开高速摩托时,疯狂连击(不是按住)加速会非常快
‘捌’ android如何去掉wheelview轮子边界
/**
* Author: wangjie
* Email: [email protected]
* Date: 7/1/14.
*/
@AILayout(R.layout.main)
public class MainActivity extends AIActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private static final String[] PLANETS = new String[]{"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Uranus", "Neptune", "Pluto"};
@AIView(R.id.main_wv)
private WheelView wva;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wva.setOffset(1);
wva.setItems(Arrays.asList(PLANETS));
wva.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
@Override
public void onSelected(int selectedIndex, String item) {
Logger.d(TAG, "selectedIndex: " + selectedIndex + ", item: " + item);
}
});
}
@AIClick({R.id.main_show_dialog_btn})
public void onClickCallbackSample(View view) {
switch (view.getId()) {
case R.id.main_show_dialog_btn:
View outerView = LayoutInflater.from(context).inflate(R.layout.wheel_view, null);
WheelView wv = (WheelView) outerView.findViewById(R.id.wheel_view_wv);
wv.setOffset(2);
wv.setItems(Arrays.asList(PLANETS));
wv.setSeletion(3);
wv.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
@Override
public void onSelected(int selectedIndex, String item) {
Logger.d(TAG, "[Dialog]selectedIndex: " + selectedIndex + ", item: " + item);
}
});
new AlertDialog.Builder(context)
.setTitle("WheelView in Dialog")
.setView(outerView)
.setPositiveButton("OK", null)
.show();
break;
}
}
}
‘玖’ android 轮播列表怎么实现
第一种:使用动画的方法实现:
这种发放需要:两个动画效果,一个布局,一个主类来实现,
public class IamgeTrActivity extends Activity {
/** Called when the activity is first created. */
public ImageView imageView;
public ImageView imageView2;
public Animation animation1;
public Animation animation2;
public TextView text;
public boolean juage = true;
public int images[] = new int[] { R.drawable.icon, R.drawable.expriment,
R.drawable.changer, R.drawable.dataline, R.drawable.preffitication };
public int count = 0;
public Handler handler = new Handler();
public Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
AnimationSet animationSet1 = new AnimationSet(true);
AnimationSet animationSet2 = new AnimationSet(true);
imageView2.setVisibility(0);
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF,
-1f, Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f);
ta.setDuration(2000);
animationSet1.addAnimation(ta);
animationSet1.setFillAfter(true);
ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.0f,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF,
0f, Animation.RELATIVE_TO_SELF, 0f);
ta.setDuration(2000);
animationSet2.addAnimation(ta);
animationSet2.setFillAfter(true);
//iamgeView 出去 imageView2 进来
imageView.startAnimation(animationSet1);
imageView2.startAnimation(animationSet2);
imageView.setBackgroundResource(images[count % 5]);
count++;
imageView2.setBackgroundResource(images[count % 5]);
text.setText(String.valueOf(count));
if (juage)
handler.postDelayed(runnable, 6000);
Log.i(handler, handler);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView) findViewById(R.id.imageView);
imageView2 = (ImageView) findViewById(R.id.imageView2);
text=(TextView)findViewById(R.id.text);
text.setText(String.valueOf(count));
//将iamgeView先隐藏,然后显示
imageView2.setVisibility(4);
handler.postDelayed(runnable, 2000);
}
public void onPause() {
juage = false;
super.onPause();
}
}
android:orientation=vertical
android:layout_width=fill_parent
android:layout_height=fill_parent
android:id=@+id/rl>
android:id=@+id/imageView
android:layout_width=fill_parent
android:background=@drawable/icon
android:layout_below=@+id/rl
android:layout_height=120dp />
android:id=@+id/imageView2
android:layout_width=fill_parent
android:background=@drawable/expriment
android:layout_below=@+id/rl
android:layout_height=120dp />
android:id=@+id/text
android:layout_width=fill_parent
android:layout_height=wrap_content
android:layout_below=@id/imageView/>
第二种:使用ViewFlipper实现图片的轮播
Android系统自带的一个多页面管理控件,它可以实现子界面的自动切换:
首先 需要为ViewFlipper加入View
(1) 静态导入:在layout布局文件中直接导入
(2) 动态导入:addView()方法
ViewPlipper常用方法:
setInAnimation:设置View进入屏幕时候使用的动画
setOutAnimation:设置View退出屏幕时候使用的动画
showNext:调用该函数来显示ViewFlipper里面的下一个View
showPrevious:调用该函数来显示ViewFlipper里面的上一个View
setFlipInterval:设置View之间切换的时间间隔
startFlipping使用上面设置的时间间隔来开始切换所有的View,切换会循环进行
stopFlipping:停止View切换
‘拾’ android图片轮播怎么实现
正常就可以实现的吧,因为这个图片还是比较轻松的,我都是使用的