android surfaceview 怎么webviewdidfinishload

当前位置:&&
本页文章导读:
&&&&?解决SurfaceView不能获取按键和触摸事件的有关问题 &&&&&& 解决SurfaceView不能获取按键和触摸事件的问题
这周有需求需要开发一个Aandroid平台的开发引擎,目的是可以降低从J2ME项目移植到Android平台的移植时间,最佳的耗时最快可以达到1......&&&&? 封闭所有activity以及减少大图片占用内存方法 &&&&&& 关闭所有activity以及减少大图片占用内存方法
1.有时候我们的程序建立很多activity,你想关闭所有,其实这是没有必要的,至于为啥 是看见别人说的,如果你非要关闭所有 有两个方法 第一个 ......&&&&? 又一个反编译凶器Apktool(转发)&&&&&& 又一个反编译利器Apktool(转发)
1.先装JAVA环境,JDK/JRE都行,官网下载 装过的就跳过吧
2.下载apktool.jar及相关文件,这里下apktool-1.0.0.tar.bz2 和apktool-install-windows-2.1_r01-1.zip
3.解压apktool.jar到......
&&&&&&最新IT科技资讯推荐:
[1]解决SurfaceView不能获取按键和触摸事件的有关问题
&&&&来源:&互联网& 发布时间:&
解决SurfaceView不能获取按键和触摸事件的问题
这周有需求需要开发一个Aandroid平台的开发引擎,目的是可以降低从J2ME项目移植到Android平台的移植时间,最佳的耗时最快可以达到1到2天,甚至是几个小时,相当于只是在J2ME增加一个移植机型。
OK,狂编代码,设计的功能都完成后,发生杯具了,测试程序居然不能获取按键事件和触摸事件。出现了可恶的提示:
No window to dispatch pointer action 0
No window to dispatch pointer action 1
视图是使用SufaceView的,代码结构和官方例子有点不同,为的是把Android的差异性隐藏起来,程序员面对的只是类似J2ME的程序框架,究竟啥原因了?
接下来的是,查资料,问高手,狂修改结构,结果没高手可以帮我解决问题,资料也找不到头绪。OK,静下心来,由0开始,重新编写一个最简单的例子,这个例子是可以获取全部事件的,再慢慢修改结构,结果加上多个功能代码后,丢失事件又出现了,噢,MY GOD!真是令人疯狂的世界。
再比较比较比较。。。
法克。。。
终于定位到问题所在。。。
原来。。。。是这样
问题出在设置屏幕全屏的那行代码,这行代码是在网上找来的:
this.getWindow().setFlags(WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.TYPE_STATUS_BAR);
但这个代码是起作用的,但它屏蔽了事件。。。
再上网找找设置屏幕全屏的代码,找到,但变成这样:
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
这又是程序员生涯中遇到的一个挫折,但又一次给解决掉,特此记录一下。。。
[2] 封闭所有activity以及减少大图片占用内存方法
&&&&来源:&互联网& 发布时间:&
关闭所有activity以及减少大图片占用内存方法
1.有时候我们的程序建立很多activity,你想关闭所有,其实这是没有必要的,至于为啥 是看见别人说的,如果你非要关闭所有 有两个方法 第一个 使用intent flag FLAG_ACTIVITY_CLEAR_TOP which brings the targeted activity to the top of the stack and closes anything else that may have been open since
他的意思是说 会保留主activity,然后关必其他的,所以你使用上面的标记之后然后finish就可以了
另一个就是startActivityForResult,这个需要你为每个activity有个反馈信息 然后受到信息关掉。
2.减少大图片占用内存的方法,最好是使用RGB_565 ,少用ARGB_8888 ,其他的尽量不用
BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.RGB_565; Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon, options);
[3] 又一个反编译凶器Apktool(转发)
&&&&来源:&互联网& 发布时间:&
又一个反编译利器Apktool(转发)
1.先装JAVA环境,JDK/JRE都行,官网下载 装过的就跳过吧
2.下载apktool.jar及相关文件,这里下apktool-1.0.0.tar.bz2 和apktool-install-windows-2.1_r01-1.zip
3.解压apktool.jar到 C:\Windows 解压apktool-install-windows.zip到任意文件夹(例如E盘根目录)
4.Win+R 运行CMD,用cd命令转到apktool-install-windows所在文件夹,输入apktool看看。会列出一些帮助的话就成功了。
Apktool 命令
apktool d XXX.apk ABC
反编译XXX.apk到文件夹ABC
从文件夹ABC重建APK,输出到ABC\dist\out.apk
然后我们反编译一枚软件玩玩…
AutoMemoryManager的免费版底部有一条广告,去掉它吧。
把com.lim.android.automemman.apk放到同文件夹(我的就是E盘根目录)
Win+R 运行CMD
E:&回车&E:\&apktool d com.lim.android.automemman.apk AMM &回车&I: Baksmaling…I: Decoding resource table…I: Decoding resources…I: Copying assets and libs…
现在文件被decode到E:\AMM了,打开E:\AMM\res\layout\main.xml看,所有都可见了吧~
编辑第59行
&com.admob.android.ads.AdView android:id=”@id/ad” android:layout_width=”fill_parent” android:layout_height=”wrap_content” admobsdk:backgroundColor=”#ff000000″ admobsdk:textColor=”#ffffffff” admobsdk:keywords=”Android application” /&
&com.admob.android.ads.AdView android:id=”@id/ad” android:layout_width=”0.0dip” android:layout_height=”0.0dip” admobsdk:backgroundColor=”#ff000000″ admobsdk:textColor=”#ffffffff” admobsdk:keywords=”Android application” /&
然后CMD输入
E:\&apktool b AMMI: Checking whether sources has changed…I: Smaling…I: Checking whether resources has changed…I: Building resources…I: Building apk file…
用Auto-sign签名E:\AMM\dist\out.apk 安装
这样广告就不见了
最新技术文章:
特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!
(C)2012-,站长邮箱:www_169it_(请将#改为@)本篇内容提取自知乎开发中,有哪些让你觉得相见恨晚的方法、类或?,其实有一部是的,但是在android开发中也算常见。大多数的函数自己还是见过的,这里记录一下备忘。同时呢,也推荐一个github,里面记录了自己日常开发中见过的比较有用的东西开发中常用的工具、链接
Throwable类中的getStackTrace()方法,根据这个方法可以得到函数的逐层调用地址,其返回值为StackTraceElement[],而在StackTraceElement类中有四个方法getClassName(),getFileName(),getLineNumber(),getMethodName()在调试打印Log时非常有用。
int num = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
StackTraceElement[] stackTrace = e.getStackTrace();
for (StackTraceElement element : stackTrace) {
String className = element.getClassName();
int lineNumber = element.getLineNumber();
String fileName = element.getFileName();
String methodName = element.getMethodName();
Log.e("TAG","fileName:"+fileName+" lineNumber:"+lineNumber+" className:"+className+" methodName"+methodName);
UncaughtExceptionHandler接口,再好的代码异常难免,利用此接口可以处理未捕获的异常。比如NullPointerException空指针异常抛出时,用户没有try catch捕获,那么,Android系统会弹出的“XXX程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。
* 异常处理类
* User:lizhangqu()
* Time: 14:48
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static final String TAG = CrashHandler.class.getSimpleName();
private Context mC
private static volatile CrashH
private Thread.UncaughtExceptionHandler defalutH
private DateFormat formatter = new SimpleDateFormat(
"yyyy-MM-dd_HH-mm-ss.SSS", Locale.CHINA);
private CrashHandler(){
* 获得单例
* @return 单例
public static CrashHandler getInstance() {
if (instance==null){
synchronized (CrashHandler.class){
if (instance==null){
instance=new CrashHandler();
public void init(Context context){
mContext=context.getApplicationContext();
defalutHandler=Thread.getDefaultUncaughtExceptionHandler();
// 获取系统默认的UncaughtException
Thread.setDefaultUncaughtExceptionHandler(this);
// 设置该CrashHandler为程序的默认处理器
public void uncaughtException(Thread thread, Throwable ex) {
boolean hasHandle=handleException(ex);
//是否处理
if (!hasHandle && defalutHandler!=null){
defalutHandler.uncaughtException(thread,ex);
//如果用户没有处理则让系统默认的异常处理器来处理
Thread.sleep(5000);
} catch (InterruptedException e) {
Log.e(TAG, "error : ", e);
android.os.Process.killProcess(android.os.Process.myPid());
private boolean handleException(final Throwable ex){
if (ex==null){
return false;
new Thread(){
public void run() {
Looper.prepare();
ex.printStackTrace();
String err="["+ex.get()+"]";
Toast.makeText(mContext, "程序出现异常,5秒后自动退出", Toast.LENGTH_LONG).show();
Looper.loop();
}.start();
String str = collectDeviceInfo(ex);
// 收集设备参数信息,日志信息
saveCrashInfoToFile(str);
// 保存日志文件
return true;
* 收集设备信息,日志信息
* @param ex Throwable
* @return 收集的信息
private String collectDeviceInfo(Throwable ex){
Log.e(TAG,"collectDeviceInfo:"+ex.getMessage());
StringBuilder builder=new StringBuilder();
return builder.toString();
* 保存出错信息
* @param error 待保存的出错信息
private void saveCrashInfoToFile(String error){
Log.e(TAG,"saveCrashInfoToFile:"+error);
程序入口进行初始化,之后未捕获的异常均由此类处理。
CrashHandler.getInstance().init(this);
Resources类中的getIdentifier(name, defType, def)方法,根据资源名称获取其ID,做UI时经常用到。
* 根据资源名获得资源id
* User:lizhangqu()
* Time: 15:18
public class ResourcesUtil {
public static final String LAYTOUT="layout";
public static final String DRAWABLE="drawable";
public static final String MIPMAP="mipmap";
public static final String MENU="menu";
public static final String RAW="raw";
public static final String ANIM="anim";
public static final String STRING="string";
public static final String STYLE="style";
public static final String STYLEABLE="styleable";
public static final String INTEGER="integer";
public static final String ID="id";
public static final String DIMEN="dimen";
public static final String COLOR="color";
public static final String BOOL="bool";
public static final String ATTR="attr";
//TODO please add other strings by yourself
public static int getResourceId(Context context,String name,String type){
Resources resources=null;
PackageManager pm=context.getPackageManager();
resources=context.getResources();
return resources.getIdentifier(name, type, context.getPackageName());
} catch (Exception e) {
e.printStackTrace();
比如获得主布局的id
ResourcesUtil.getResourceId(getApplicationContext(),"activity_main",ResourcesUtil.LAYTOUT);
View中的isShown()方法,以前都是用view.getVisibility() == View.VISIBLE来判断的,但是与这个函数还是有区别的。也就是只有当view本身和它的所有父容器都是visible时,isShown()才返回TRUE。而平常我们调用if(view.getVisibility() == View.VISIBLE)只是对view本身而不对父容器的可见性进行判断。
集合与数组的转化,Arrays类中的asList(T… array)方法,数组转List集合;反过来List.toArray();
android.text.format.Formatter类中formatFileSize(Context, long)方法,用来格式化文件大小(B → KB → MB → GB)
android.text.format.Formatter.formatFileSize(getApplicationContext(),1024);
//返回1.00KB
android.text.format.Formatter.formatFileSize(getApplicationContext(),1024*1024)
//返回1.00MB
android.media.ThumbnailUtils类,用来获取媒体(、视频)缩略图,该类从Android 2.2开始系统新增,不向下兼容
* 创建一张视频的缩略图
* 如果视频已损坏或者格式不支持可能返回null
* @param filePath 视频文件路径
如:/sdcard/android.3gp
* @param kind kind可以为MINI_KIND或MICRO_KIND
ThumbnailUtils.createVideoThumbnail(filePath,kind);
* 创建一个指定大小的缩略图
* @param source (Bitmap类型)
* @param width
压缩成的宽度
* @param height 压缩成的高度
ThumbnailUtils.extractThumbnail(source , width, height);
* 创建一个指定大小居中的缩略图
* @param source 源文件(Bitmap类型)
* @param width
输出缩略图的宽度
* @param height 输出缩略图的高度
* @param options 如果options定义为OPTIONS_RECYCLE_INPUT,则回收@param source这个资源文件
* (除非缩略图等于@param source)
ThumbnailUtils.extractThumbnail(source , width, height,options);
格式化,可以使用String类的format(String,Object…)方法,如果要格式化资源文件strings.xml中的字符串,可以使用getResources().getString(int,Object…)方法
String.format("money:¥%.2f",1.00);
&resources&
&string name="format"&money:$%.2f&/string&
&/resources&
getResources().getString(R.string.format,1.00);
View类中的三个方法:callOnClick(),performClick(),performLongClick(),可以直接用于触发View的点击事件,不用我们手动点击才触发;
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.e("TAG", "onClick");
findViewById(R.id.btn).setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
Log.e("TAG", "onLongClick");
return true;
findViewById(R.id.btn).callOnClick();
findViewById(R.id.btn).performClick();
findViewById(R.id.btn).performLongClick();
至于callOnClick()和performClick的区别,相信看过源码后你会一目了然。
* Call this view's OnClickListener, if it is defined.
Performs all normal
* actions associated with clicking: reporting accessibility event, playing
* a sound, etc.
* @return True there was an assigned OnClickListener that was called, false
otherwise is returned.
public boolean performClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
ListenerInfo li = mListenerI
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
return true;
return false;
* Directly call any attached OnClickListener.
Unlike {@link #performClick()},
* this only calls the listener, and does not do any associated clicking
* actions like reporting an accessibility event.
* @return True there was an assigned OnClickListener that was called, false
otherwise is returned.
public boolean callOnClick() {
ListenerInfo li = mListenerI
if (li != null && li.mOnClickListener != null) {
li.mOnClickListener.onClick(this);
return true;
return false;
TextUtils类中的isEmpty(String)方法,判断字符串是否为null或”“,不要再自己写判断字符串非空的代码了。
String str =
String str1 = "";
String str2 = "a";
Log.e("TAG", TextUtils.isEmpty(str)+" "+TextUtils.isEmpty(str1)+" "+TextUtils.isEmpty(str2));
//输出true true false
类似的方法还有TextUtils.isDigitsOnly()是否是纯数字
TextView类中的append(String)方法,添加文本,不要再使用getText()方法拿到旧的字符串再拼接,拼接好了之后再调用setText()方法了
TextView textview= (TextView) findViewById(R.id.tv);
textview.setText("aaa");
textview.append("bbb");
View类中的getDrawingCache()等一系列方法,目前只知道可以用来截图
* / 获取指定Activity的截屏,保存到png文件
* @param activity activity
* @return 截屏Bitmap
private static Bitmap takeScreenShot(Activity activity) {
// View是你需要截图的View
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
// 获取状态栏高度
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.
Log.i("TAG", "" + statusBarHeight);
// 获取屏幕长和高
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay()
.getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
- statusBarHeight);
view.destroyDrawingCache();
DecimalFormat类,用于字串格式化包括指定位数、百分数、科学计数法等
DecimalFormat df=new DecimalFormat("0.0");
df.format(12.34);
System类中的arraycopy(src, srcPos, dest, destPos, length)方法,用来copy数组;Arrays.copyOf()里的一系列方法也是间接调用System.arraycopy()方法
Fragment类中的onHiddenChanged(boolean)方法,使用FragmentTransaction中的hide(),show()时貌似Fragment的其它生命周期方法都不会被调用
调用hide或者show你就会发现fragment的生命周期不走了!onPause方法不调用了!onResume只调用一次!这时此时方法onHiddenChanged派上用场
当fragment隐藏时,该方法会调用传入参数为true表示该fragment被隐藏了,
当fragment调用了show方法后,该方法传入的参数为false,表示该fragment正在显示
所以总结起来,如果使用hide/show方法来控制fragment的使用时,原本需要在onResume以及onPause方法做的事情就可以迁移到onHiddenChanged时进行管理
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if(hidden){
this.onPause();
this.onResume();
Activity类中的onWindowFocusChanged(boolean)方法,使用一个view的getWidth() getHeight() 方法来获取该view的宽和高,返回的值却为0。
如果这个view的长宽很确定不为0的话,那很可能是你过早的调用这些方法,也就是说在这个view被加入到rootview之前你就调用了这些方法,返回的值自然为0.,解决该问题的方法有很多,主要就是延后调用这些方法。可以试着在onWindowFocusChanged()里面调用这些方法。
View类中的getLocationInWindow(int[])方法和getLocationOnScreen(int[])方法,获取View在窗口/屏幕中的位置
TextView tv= (TextView) findViewById(R.id.tv);
int loc[]=new int[2];
tv.getLocationInWindow(loc);
Log.e("TAG",loc[0]+" "+loc[1]);
TextView类中的setTransformationMethod(TransformationMethod)方法,可用来实现“显示密码”功能;
TextView tv= (TextView) findViewById(R.id.tv);
tv.setText("123456");
tv.setTransformationMethod(PasswordTransformationMethod.getInstance());
TextWatcher接口,用来监听文本输入框内容的改变,可以做的事很多
View类中的setSelected(boolean)方法结合android:state_selected=”“用来实现图片选中效果
Surface设置透明,但是会挡住其它控件
SurfaceView.setZOrderOnTop(true);
SurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
ListView或GridView类中的setFastScrollEnabled(boolean)方法,用来设置快速滚动滑块是否可见,当然前提是item够多
PageTransformer接口,用来自定义ViewPager页面切换动画,用setPageTransformer(boolean, PageTransformer)方法来进行设置
apache提供的一系列jar包:commons-lang.jar,commons-collections.jar,commons-beanutils.jar等,里面很多方法可能是你曾经用几十几百行代码实现过的,但是执行效率或许要差很多,比如:ArrayUtils,StringUtils……
AndroidTestCase类,Android单元测试
Activity类中的onNewIntent(intent)方法,具体看这篇文章Android:onNewIntent()触发机制及注意事项
Activity.startActivities() 常用于在中间启动其他的Activity。和startActivity()类似,startActivities也是界面跳转,但是传入的intent是一个数组,也就是说是多个。假设我传入的是两个intent: I1和I2,则调用startActivities之后,直接到I2界面,按返回键,到I1界面。其中到I2的过程中,不会经过I1界面,也就是说,不过存在I1的生命周期之说。
Html.fromHtml() 用于生成一个Html,参数可以是一个字符串.但是它不是很快,所以不要经常去用.取而代之的是请手动构建 Spannable 来替换 Html.fromHtml,但是它对渲染从 web 上获取的文字还是很不错的。
TextView.setError() 在验证用户输入的时候很棒
Build._CODES 这个标明了当前的,在处理问题的时候经常会用到.点进去可以看到各个版本的不同特性
Log.getStackTraceString() 方便的日志类工具,方法Log.v()、Log.d()、Log.i()、Log.w()和Log.e()都是将信息打印到LogCat中,有时候需要将出错的信息插入到或一个自定义的日志文件中,那么这种情况就需要将出错的信息以字符串的形式返回来,也就是使用static String getStackTraceString(Throwable tr)方法的时候。
LayoutInflater.from() 顾名思义,用于Inflate一个layout,参数是layout的id.很多地方都会用到
LayoutInflater.from(getApplicationContext()).inflate(int resource, ViewGroup root, boolean attachToRoot)
ViewConfiguration.getScaledTouchSlop() 使用 ViewConfiguration 中提供的值以保证所有触摸是的交互都统一的。这个方法获取的值表示:用户的手滑动这个距离后,才判定为正在进行滑动.当然这个值也可以自己来决定.但是为了一致性,还是使用标准的值较好。
PhoneNumberUtils.convertKeypadLettersToDigits 顾名思义.将字母转换为数字,类似于T9输入法
String abcd = PhoneNumberUtils.convertKeypadLettersToDigits("abcd");
Log.e("TAG",abcd);
//结果为2223
Context.getCacheDir() 获取缓存数据的路径,这个路径通常在SD卡上(这里的SD卡指的是广义上的SD卡,包括外部和内部存储)Adnroid/data/您的应用程序包名/cache/ 下面.测试的时候,可以去这里面看是否缓存成功.缓存在这里的好处是:不用自己再去手动创建文件夹,不用担心用户把自己创建的文件夹删掉,在应用程序卸载的时候,这里会被清空,使用第三方的清理工具的时候,这里也会被清空。
ArgbEvaluator 用于处理颜色的渐变。在使用动画的时候可能用的比较多。可以看下他的实现
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startV
int startA = (startInt && 24) & 0xff;
int startR = (startInt && 16) & 0xff;
int startG = (startInt && 8) & 0xff;
int startB = startInt & 0xff;
int endInt = (Integer) endV
int endA = (endInt && 24) & 0xff;
int endR = (endInt && 16) & 0xff;
int endG = (endInt && 8) & 0xff;
int endB = endInt & 0xff;
return (int)((startA + (int)(fraction * (endA - startA))) && 24) |
(int)((startR + (int)(fraction * (endR - startR))) && 16) |
(int)((startG + (int)(fraction * (endG - startG))) && 8) |
(int)((startB + (int)(fraction * (endB - startB))));
ContextThemeWrapper 方便在运行的时候修改。这里以改变系统自带Dialog字体大小为例
//将一个style的parent设置为@android:style/Theme.Dialog
//修改其中的 &item name="android:textSize"&30sp&/item&
//利用context和该style生成ContextThemeWrapper
//利用ContextThemeWrapper生产Builder对象
ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(MainActivity.this, R.style.dialog);
AlertDialog.Builder builder =
new AlertDialog.Builder(contextThemeWrapper);
Dialog dialog=builder.create();
Space 它是Android 4.0中新增的一个控件,它实际上可以用来分隔不同的控件,其中形成一个空白的区域.这是一个轻量级的视图组件,它可以跳过Draw,对于需要占位符的任何场景来说都是很棒的。
android:layout_width="match_parent"
android:layout_height="10dp"/&
ValueAnimator.reverse() 用在动画中,将动画逆向。
EditText类的setKeyListener(KeyListener)方法,设置DigitsKeyListener类将只能输入数字,通过DigitsKeyListener.getInstance(String accepted)方法即可指定EditText可输入的字符集。
DateUtils.formatDateTime() 用来进行区域格式化工作,输出格式化和本地化的时间或者日期。
android.text.format.DateUtils.formatDateTime(getApplicationContext(),System.currentTimeMillis(), DateUtils.FORMAT_SHOW_DATE|DateUtils.FORMAT_SHOW_YEAR|DateUtils.FORMAT_SHOW_TIME);
Linkify.addLinks() 在Text上添加链接。很实用。比如将TextView中的超链接识别为可点击进入的链接。
TextView tv= (TextView) findViewById(R.id.tv);
Linkify.addLinks(tv,Linkify.WEB_URLS);
StaticLayout 在自定义 View 中渲染文字的时候很实用。
使用Canvas的drawText绘制文本是不会自动换行的,即使一个很长很长的字符串,drawText也只显示一行,超出部分被隐藏在屏幕之外。可以逐个计算每个字符的宽度,通过一定的算法将字符串分割成多个部分,然后分别调用drawText一部分一部分的显示, 但是这种显示效率会很低。
StaticLayout是android中处理文字换行的一个工具类,StaticLayout已经实现了文本绘制换行处理
Activity.onBackPressed() 很方便的管理back键的方法,有时候需要自己控制返回键的事件的时候,可以重写一下。比如加入 “点两下back键退出” 功能。
GestureDetector 用来监听和相应对应的手势事件,比如点击,长按,慢滑动,快滑动,用起来很简单,比你自己实现要方便许多。
ActivityManager.getMemoryClass() 告诉你你的机器还有多少内存,在计算缓存大小的时候会比较有用。
ViewStub 它是一个初始化不做任何事情的 View,但是之后可以载入一个布局文件。在慢加载 View 中很适合做占位符。
SystemClock.sleep() 这个方法在保证一定时间的 sleep 时很方便,通常用来进行 debug 和模拟延时。
Thread.sleep()是java提供的函数。在调用该函数的过程中可能会发生InterruptedException异常。
SystemClock.sleep()是android提供的函数。在调用该函数的过程中不会发生InterruptedException异常。
DisplayMetrics.density 这个方法你可以获取设备像素密度,大部分时候最好让系统来自动进行缩放资源之类的操作,但是有时候控制的效果会更好一些.(尤其是在自定义View的时候)。
Pair.create(),这个类在v4包下也存在,内部就两个泛型对象,一个叫first,一个叫second,可以类比map,一个为key,一个为value,但是这个Pair不是key,value,而是一组数据
Fragment.setArguments,因为在构建 Fragment 的时候不建议加参数,所以这是个很好的东西,可以在创建 Fragment 之前设置参数
public class BlankFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public static BlankFragment newInstance(String param1, String param2) {
BlankFragment fragment = new BlankFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
DialogFragment.setShowsDialog ()
这是一个很巧妙的方式,DialogFragment 可以作为Dialog显示。可以参考这篇文章Android 官方推荐 : DialogFragment 创建对话框
FragmentManager.enableDebugLogging () 在需要观察 Fragment 状态的时候会有帮助。可以通过getFragmentManager().enableDebugLogging(true);来提供相关的debug功能。
LocalBroadcastManager 这个会比全局的 broadcast 更加,简单,快速。一个简单的应用就是退出程序。
* 全局Application基类
* User:lizhangqu()
* Time: 09:35
public class BaseApplication extends Application {
public final static String ACTION_EXIT_APP = "package.exit";
private static LocalBroadcastManager mLocalBroadcatM
private static Context mC
private static BaseA
public static Context getContext() {
public void onCreate() {
super.onCreate();
instance = this;
mContext = this.getApplicationContext();
CorePageManager.getInstance().init(this);
* 发送本地广播退出程序
public void exitApp() {
Intent intent = new Intent();
intent.setAction(ACTION_EXIT_APP);
intent.addCategory(Intent.CATEGORY_DEFAULT);
BaseApplication.getLocalBroadcastManager().sendBroadcast(intent);
BaseActivity.unInit();
* 获得LocalBroadcastManager对象
* @return LocalBroadcastManager对象
public static LocalBroadcastManager getLocalBroadcastManager() {
if (mLocalBroadcatManager == null) {
mLocalBroadcatManager = LocalBroadcastManager.getInstance(mContext);
return mLocalBroadcatM
public class BaseActivity extends FragmentActivity{
public final static String ACTION_EXIT_APP = "package.exit";
* 仅用于接受应用退出广播,程序退出时有机会做一些必要的清理工作
private BroadcastReceiver mExitReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_EXIT_APP)) {
Log.d(TAG,"exit from broadcast");
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
IntentFilter filter = new IntentFilter();
filter.addAction(Config.ACTION_EXIT_APP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
BaseApplication.getLocalBroadcastManager().registerReceiver(mExitReceiver, filter);
//注册本地广播,接收程序退出广播
Application.registerActivityLifecycleCallbacks 就是注册 Activity 的生命周期的一些回调方法,就是一个方便的工具
Application通过此接口提供了一套回调方法,用于让对Activity的生命周期事件进行集中处理。
以往若需监测Activity的生命周期事件代码,你可能是这样做的,重写每一个Acivity的onResume(),然后作统计和处理。
protected void onResume() {
super.onResume();
//TODO 处理和统计代码
Log.v(TAG, "onResume");
Logger.v(TAG, "onResume");
Logging.v(TAG, "onResume");
ActivityLifecycleCallbacks接口回调可以简化这一繁琐过程,在一个类中作统一处理
android.app.Application.ActivityLifecycleCallbacks 它要求API 14+ (Android 4.0+),在我们自定义的Application注册回调。
public void onCreate() {
super.onCreate();
this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
public void onActivityStopped(Activity activity) {
Logger.v(activity, "onActivityStopped");
public void onActivityStarted(Activity activity) {
Logger.v(activity, "onActivityStarted");
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Logger.v(activity, "onActivitySaveInstanceState");
public void onActivityResumed(Activity activity) {
Logger.v(activity, "onActivityResumed");
public void onActivityPaused(Activity activity) {
Logger.v(activity, "onActivityPaused");
public void onActivityDestroyed(Activity activity) {
Logger.v(activity, "onActivityDestroyed");
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Logger.v(activity, "onActivityCreated");
这里只是使用Log日志工具作简要测试,如需满足较复杂的统计或调试需求时,此法可能会大大减少插入代码量,提高效率,更多详情请看这个项目AndroidLifecyle
versionNameSuffix这个 gradle 设置可以让你在基于不同构建类型的 manifest 中修改版本名这个属性,例如,如果需要在在 debug 版本中以”-SNAPSHOT”结尾,那么就可以轻松的看出当前是 debug 版还是 release 版。
buildTypes {
versionNameSuffix "sample"
-nodpi 在没有特别定义的情况下,很多修饰符(-mdpi,-hdpi,-xdpi等等)都会默认自动缩放 assets/dimensions,有时候我们需要保持显示一致,这种情况下就可以使用 -nodpi。
Activity.recreate () 强制让 Activity 重建
BroadcastRecevier.setDebugUnregister ()什么用不知道,调试用的。
android:weightSum (LinearLayout)这个很有用,在百分比布局没有出来前,基本上就是通过这个属性以及layout_weight属性来间接达到百分比。
android:duplicateParentState (View) 此方法可以使得子 View 可以复制父 View 的状态。比如如果一个 ViewGroup 是可点击的,那么可以用这个方法在它被点击的时候让它的子 View 都改变状态。
android:tileMode (BitmapDrawable)可以指定图片使用重复填充的模式。
android:enterFadeDuration/android:exitFadeDuration (Drawables)此属性在 Drawable 具有多种状态的时候,可以定义它展示前的淡入淡出效果。
android:scaleType (ImageView)定义在 ImageView 中怎么缩放/剪裁图片,一般用的比较多的是centerCrop和centerInside。
Merge此标签可以在另一个布局文件中包含别的布局文件,而不用再新建一个 ViewGroup,对于自定义 ViewGroup 的时候也需要用到;可以通过载入一个带有标签的布局文件来自动定义它的子部件。
AtomicFile通过使用备份文件进行文件的原子化操作的类
ViewDragHelper视图拖动是一个比较复杂的问题。这个类可以帮助解决不少问题。可以参考这篇文章Android ViewDragHelper完全解析 自定义ViewGroup神器
**PopupWindow**Android到处都在使用PopupWindow ,甚至你都没有意识到(标题导航条ActionBar,自动补全AutoComplete,编辑框错误提醒Edittext Errors)。这个类是创建浮层内容的主要方法。
**SparseArray**Map的高效优化版本。推荐了解姐妹类SparseBooleanArray、SparseIntArray和SparseLongArray。在编写通用适配器的时候SparseArray可能会用到
PackageManager.setComponentEnabledSetting()可以用来启动或者禁用程序清单中的组件。对于关闭不需要的功能组件是非常赞的,比如关掉一个当前不用的广播接收器。
SQLite.yieldIfContendedSafely()让你暂时停止一个数据库事务, 这样你可以就不会占用太多的系统资源。
Environment.getExternalStoragePublicDirectory()还是那句话,用户期望在SD卡上得到统一的用户体验。用这个方法可以获得在用户设备上放置指定类型文件(、图片等)的正确目录。
Context.getExternalFilesDir()申请了SD卡写权限后,你可以在SD的任何地方写数据,把你的数据写在设计好的合适位置会更加有礼貌。这样数据可以及时被清理,也会有更好的用户体验。此外,Android 4.0 Kitkat中在这个文件夹下写数据是不需要权限的,每个用户有自己的独立的数据存储路径。该API从V8才开始支持。
View.generateViewId()每次我都想要推荐生成控件的ID。需要注意的是,不要和已经存在的控件ID或者其他已经生成的控件ID重复。
ActivityManager.clearApplicationUserData() 一键清理你的app产生的用户数据,可能是做用户退出登录功能,有史以来最简单的方式了。以前自己的做法真是不忍直视啊。
ActivityOptions方便的定义两个Activity切换的动画。 使用ActivityOptionsCompat 可以很好解决旧版本的兼容问题。使用ActivityOptionsCompat 类可以很方便的实现Material Design的切换动画
ViewParent.requestDisallowInterceptTouchEvent() Android系统触摸事件机制大多时候能够默认处理,不过有时候你需要使用这个方法来剥夺父级控件的控制权。
Fragment 的 setUserVisibleHint方法,可实现 fragment 对用户可见时才加载资源(延迟加载)
IntentService一个可以干完活后自己去死且不需要我们去管理子线程的Service
Executors. newSingleThreadExecutor()单线程顺序执行的任务队列
**android:animateLayoutChanges=”true”**LinearLayout中添加View的动画的办法,支持通过setLayoutTransition()自定义动画
GradientDrawable渐变,可实现阴影效果
PointF,graphics包中的一个类,我们经常见到在处理Touch事件的时候分别定义一个downX,一个downY用来存储一个坐标,如果坐标少还好,如果要记录的坐标过多那代码就不好看了。用PointF(float x, float y);来描述一个坐标点会清楚很多。
StateListDrawable,定义Selector通常的办法都是xml文件,但是有的时候我们的图片资源可能是从动态获取的,比如很多app所谓的皮肤,这种时候就只能通StateListDrawable来完成了,各种addState即可。
includeFontPadding=”false”,TextView默认上下是有一定的padding的,有时候我们可能不需要上下这部分留白,加上它即可。
onTrimMemory,在Activity中重写此方法,会在内存紧张的时候回调(支持多个级别),便于我们主动的进行资源释放,避免OOM。
Fragment在onAttach方法中接收回调
public void onAttach(Activity activity) {
super.onAttach(activity);
mPageSelectedListener = (PageSelectedListener)
mMenuBtnOnclickListener = (MenuBtnOnClickListener)
mCommitBtnOnClickListener = (CommitBtnOnClickListener)
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + "must implements listener");
通过 WindowManager.addView 在其他app界面添加一个view时,经常会无法显示,特别在miui,emui固件上,需要指定type为LayoutParams.TYPE_TOAST。
Paint.setXfermode(porterDuffXfermode),在ApiDemo里面有专门的介绍,实现了穿透,叠加,覆盖等多种绘制效果,非常实用。在自定义View中用的比较多。
通过View.getDrawingCache()可以获取截图,但是需要setDrawingCacheEnabled(true)频繁使用可能会oom,还有一种方法直接用canvas
Bitmap bm = Bitmap.createBitmap((int) (w * scale), (int) (h*scale), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas();
canvas.setBitmap(bm);
View.draw(canvas);
return bm;
由于fragment的缓存机制决定的。默认情况下,viewpager切换页面时会缓存上一个页面,非相邻页面被销毁,可以使用viewPaper.setOffscreenPageLimit()函数来解决
support library 里的任何东西你都值得去看看
fragment嵌套时,内部fragment的manager通过getChildFragmentManager()获得
布局中,view.bringTofont(),把该view在层叠布局中置于最前面。通样的viewgroup的bringChildtoFont(),都是一样的效果。
版权声明:本文为博主原创文章,未经博主允许不得转载。

我要回帖

更多关于 android的surfaceview 的文章

 

随机推荐