android中Handler.removeCallbacksAndMessages(null)的作用

 更新时间:2016年9月20日 19:59  点击:1747
最近在学习android应用开发了,但看到一段代码中有一句Handler.removeCallbacksAndMessages(null)当时搞不明白为什么时候会是移除空了,后来参考了一些资料才知识,下面一起来看看。

今天都到一段代码,在onDestroy()方法中,使用了下面的代码:


mHandler.removeCallbacksAndMessages(null);
 
一开始我完全看不懂,我为什么参数是null,如果是null还需要移除什么Callbacks和Messages。后来察看官方文档有以下说明:

地址:http://developer.android.com/reference/android/os/Handler.html#removeCallbacksAndMessages%28java.lang.Object%29

 
public final void removeCallbacksAndMessages(Object token)

Added in API level 1
Remove any pending posts of callbacks and sent messages whose obj istoken. If token is null, all callbacks and messages will be removed.
 

上面的意思是说,如果参数为null的话,会将所有的Callbacks和Messages全部清除掉。
 

这样做的好处是在Acticity退出的时候,可以避免内存泄露。

下面给大家分享一篇关于利用ListView实现圆弧列表的方法,希望此教程对各位安卓开发者会带来帮助哦。
简介
制作一个垂直列表非常常见也很简单,如下所示:
Android使用ListView实现圆弧列表例子
但是我们如何创建一个可以圆弧型的列表呢?就像下面的效果:
Android使用ListView实现圆弧列表例子
如何实现?
当然,我们必须定制一个视图来创建一个那样的列表。我决定使用SurfaceView 来创建这个列表视图。经过分析之后,该问题包含如下内容:
  • 如何在圆弧内绘制图片?
  • 如何让列表按照圆弧的轨迹滑动?
如何在圆弧内绘制图片?
假设有一个带中心点的圆弧(centerX, centerY)和半径r。一个点P有相对于中心点的角度。那么下面的公式就可以描述出该问题:
  • P(x) =  centerX + cos(alpha) *r.
  • P(y) = centerY - sin(alpha) * r.
基于此,我们可以很方便的在圆弧上绘制一个列表项.
如何在圆弧上滑动列表视图?
当用户滑动列表时,会出现该问题。我们如何更新每个列表项的角度?确切的说,我们必须详细记录滑动的角度。之后添加到当前列表视图中每一项的角度中。为了解决这个要求。我决定使用GestureDetector 来控制这个事件。同时,在这个类中,我主要考虑的是如何详细记录滑动的角度(函数名如下).
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
基于e2, distanceX, 和 distanceY,滑动的角度将被详细记录到下面的图片中:
Android使用ListView实现圆弧列表例子
基于此图片,我们给出了下面的公式
Android使用ListView实现圆弧列表例子
=> scroll angle = β - α
代码

我讲创建一个展示的列表作为样例。列表中的图片来自于资源文件夹。你可以参考我上传的源代码.

 代码如下 复制代码

int[] playerDrawableResourceIds = new int[] { R.drawable.ronaldo,
            R.drawable.zindance, R.drawable.congvinh, R.drawable.huynhduc,
            R.drawable.gerrard, R.drawable.nagatomo, R.drawable.messi,
            R.drawable.minhphuong, R.drawable.neymar, R.drawable.ronaldo_beo,
            R.drawable.ronaldinho, R.drawable.xavi };


如何在圆弧中绘制图片?

首先,创建一个列表项的类CircleDrawItem.

 代码如下 复制代码
 
public class CircleDrawItem {
    public Bitmap mIconBitmap;
    public double mAngle;
}

    mIconBitmap: 列表项的位图.

    mAngle: 每个列表项的弧度。这个弧度在旋转列表项的时候会被更新.

因为该圆弧将被在屏幕左侧展示。所以圆心将会把X坐标设置为负数。同时,Y坐标将被设置为屏幕中心的Y坐标值.
 

 代码如下 复制代码
mCenterX = (int) (-Global.dp * 200);
mCenterY = (int) (Global.dh / 2.0f);
mRadius = (int) (450 * Global.dp);
mStartAngleInRadian = Math.PI / 4;


用Global 的值进行计算:

 代码如下 复制代码
 
Global.dw = getResources().getDisplayMetrics().widthPixels;
Global.dh = getResources().getDisplayMetrics().heightPixels;
Global.dp = Global.density / 1.5f;


这个圆弧保有CircleDrawItem的数组列表。第一项的弧度为PI/4。每个列表项的间隔是PI/10.第一项的弧度和两项间的弧度可以根据你的需求进行修改。

 

 代码如下 复制代码
for (int i = 0; i < playerDrawableResourceIds.length; i++) {
    CircleDrawItem circleDrawItem = new CircleDrawItem();
    circleDrawItem.mIconBitmap = decodeSampledBitmapFromResource(
            getResources(), playerDrawableResourceIds[i], 50, 50);
    circleDrawItem.mAngle = mStartAngleInRadian - i * Math.PI / 10;
    datas.add(circleDrawItem);     
}

我创建了一个线程,以便将每个数据项绘制到圆弧中。

 代码如下 复制代码
 
protected void draw() {
    Canvas canvas = getHolder().lockCanvas();
    if (canvas == null) {
        return;
    }
    canvas.save();
    canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setFilterBitmap(true);
    paint.setAntiAlias(true);
 
    for (int i = 0; i < datas.size(); i++) {
        canvas.save();
        CircleDrawItem item = datas.get(i);
        double x = mCenterX + Math.cos(item.mAngle) * mRadius;
        double y = mCenterY - Math.sin(item.mAngle) * mRadius;
        canvas.drawBitmap(item.mIconBitmap,
                (int) x - item.mIconBitmap.getWidth() / 2, (int) y
                        - item.mIconBitmap.getHeight() / 2, paint);
        canvas.restore();
    }
    canvas.restore();
    getHolder().unlockCanvasAndPost(canvas);
}

如何让列表在圆弧中滑动?

引用OnGestureListener 并重载onScroll()函数。

 代码如下 复制代码

 
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
        float distanceY) {
    float tpx = e2.getX();
    float tpy = e2.getY();
    float disx = (int) distanceX;
    float disy = (int) distanceY;
    double scrollAngle = calculateScrollAngle(tpx, tpy, tpx + disx, tpy
            + disy);
    for (int i = 0; i < datas.size(); i++) {
        datas.get(i).mAngle += scrollAngle;
    }
    return true;
}

计算滑动角度的方法如下:

 代码如下 复制代码

 
private double calculateScrollAngle(float px1, float py1, float px2,
        float py2) {
    double radian1 = Math.atan2(py1, px1);
    double radian2 = Math.atan2(py2, px2);
    double diff = radian2 - radian1;
    return diff;
}

如果你想制作自己的Android天气应用,那么你来对地方了.没有比使用Google Weather API XML解析更简单的方法了.所以你只需要知道如何解析XML即可.

背景
我们需要简单的访问XML来解析XML文档.因此,你只要知道在XML文档代码里结果的位置地方,然后解析它就很简单.举个例子,在下面这张图里,我们想要知道有关突尼斯的斯法克斯的天气:

一开始,我们需要指定我们想要知道天气的城市或者州.

 代码如下 复制代码

String c = city.getText().toString();
        String s = state.getText().toString();
        StringBuilder URL = new StringBuilder(BaseURL);
        URL.append(c+","+s);
        String fullUrl= URL.toString();
        try
        {
            URL website= new URL(fullUrl);
            //getting xmlReader to parse data
            SAXParserFactory spf= SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader() ;
            HandlingXmlStuff doingWork = new HandlingXmlStuff();
            xr.setContentHandler(doingWork);
            xr.parse(new InputSource(website.openStream()));
            String information = doingWork.getInformation();
            tv.setText(information);
        }
        catch(Exception e)
        {
            tv.setText("error");
        }

然后, 我们开始解析XML文档.

 代码如下 复制代码

public class HandlingXmlStuff extends DefaultHandler {
XMLDataCollected info = new XMLDataCollected();
public String getInformation()
{
    return info.dataToString();
}
 
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        if (localName.equals("city"))
        {
            String city=attributes.getValue("data");
            info.setCity(city);
        }else if (localName.equals("temp_f")){
            String t = attributes.getValue("data");
            int temp = Integer.parseInt(t);
            info.setTemp(temp);
        }     
    }
}

我们需要指定我们的数据模型和使用的功能.

 代码如下 复制代码
public class XMLDataCollected {
    int temp= 0;
    String city=null ;
    public void setCity(String c)
    {
        city= c ;
    }
    public void setTemp(int t )
    {
        temp = t ;
    }
    public String dataToString()
    {
        return "In"+city+" the current Temp in F is "+ temp+" degrees";
    }
} 。

兴趣点
在这个方案里, 你学会了在Android应用里如何使用XML解析来轻松制作许多功能

 

在Unity工程的Assets目录内,有一些文件夹的名称具有特殊意义,有专门的用途,将其收集列举如下.


ActionScript
存放Flash的ActionScript脚本。当游戏被导出为Flash格式的时候,这里的脚本会自动替换指定的C#脚本。

Editor
存放编辑器脚本。

Gizmos

通常是存放TIF格式的图片,在OnDrawGizmos函数内使用Gizmos.DrawIcon将其画为图标在场只中显示。

Plugins/Android

存放Android插件,包括.jar或XML文件等。

Plugins/iOS

存放iOS插件,包括.a或.m 或 .mm文件等。

Resources

存放使用Resources.Load()动态读取的资源,它们可以是图片、模型等不同类型的资源。

Standard Assets

标准Unity资源包。

StreamingAssets
独立存放到文件系统中媒体文件,如视频等。

WebPlayerTemplates
存放网页游戏模版,其中的每个模版均以-个自定义名称的子目录形式存放。

在平时我们开发应用的过程中,我们可能需要设置一些动态变量值随着我们版本的变化一起变化 。在这种情况下,一般我们首先想到的办法可能就是我们申明一个静态的变量,然后在我们的应用中直接使用就行了,以后如果需要修改的时候,我们再找到这个类 里面的定义的地方,再重新赋值即可

当然,我们也可以通过在Menifest里面的meta-data标签来定义一个值,然后在我们的应用中直接去读取即可,这样,下次如果需要修改值,我们就不必再找到我们的代码了,而是在修改我们的版本号的时候,一起就可以修改了。更加方便与便捷。

这样的应用场景在给多市场打包的时候,你一定见过。比如友盟,有米的sdk里面就有一步为:在 application标签下定义一个meta-data来为不同的市场赋值和传入不同的appId。

那么我们的自己应用里面应该如何去定义meta-data的值呢?并且怎么在代码中取出我们要想的值 呢?

那么点击更多,跟着我一起来看看如何操作吧!!!

形如:

 代码如下 复制代码
<application ...>
<meta-data android:value="12345" android:name="APPID"/>
<activity ...>
<meta-data android:name="data_Name" android:value="hello my activity"></meta-data>
</activity>
</application>

从上面可以看出,我们的meta-data不仅仅是可以放到application标签下面,也可以放到activity下面,其实也可以放到service ,receiver下面。。。

我们分别来看看如何获取的吧?

1.获取 application标签中的meta-data:
形如:

 

 代码如下 复制代码

<application...>
<meta-data android:value="my_data" android:name="data_Name"/>
</application>
代码:

ApplicationInfo appInfo = context.getPackageManager()
.getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String dataName=appInfo.metaData.getString("data_Name");

2.获取 activity标签中的meta-data:
形如:

 代码如下 复制代码

<activity ...>
<meta-data android:value="my_activity" android:name="data_Name"/>
</activity>

代码:

 代码如下 复制代码
ActivityInfo activityInfo = context.getPackageManager()
. getActivityInfo(activity.getComponentName(),
PackageManager.GET_META_DATA);
String dataName=activityInfo.metaData.getString("data_Name");

注意:activity.getComponentName()为获取activity实例的ComponentName 也可以用下面的代替:

 代码如下 复制代码
//通过指定一个activity类来生成一个新的ComponentName
ComponentName componentName =new ComponentName(context, SplashActivity.class);

3.获取 service标签中的meta-data:
形如:

 代码如下 复制代码
< service ...>
<meta-data android:value="my_service" android:name="data_Name"/>
</service >

代码:

 代码如下 复制代码
ComponentName componentName=new ComponentName(context, MyService.class);
ServiceInfo serviceInfo = context.getPackageManager()
. getServiceInfo(componentName,
PackageManager.GET_META_DATA);
String dataName=serviceInfo.metaData.getString("data_Name");

注意:在Service里面就没有getComponentName()方法来快速获取到当前的ComponentName了,所以只能通过指定service类的方式来生成一个新的ComponentName

4.获取 receiver标签中的meta-data:
形如:

 代码如下 复制代码
< receiver ...>
<meta-data android:value="my_receiver" android:name="data_Name"/>
</receiver >

代码:

 代码如下 复制代码
ComponentName componentName=new ComponentName(context, MyService.class);
ActivityInfo activityInfo = context.getPackageManager()
. getReceiverInfo(componentName,
PackageManager.GET_META_DATA); www.111cn.net
String dataName=activityInfo.metaData.getString("data_Name");

注意:在receiver可没有 ReceiverInfo了,而是用的activityInfo来处理的。

最后的注意:我们在获取值的时候都是使用的 是:xxxInfo.metaData.getString(“data_Name”);把所有的值都当成是String来获取的,如果在meta- data中是int型的,如果还是使用getString()方法获取出来的值是为空的,但是metaData提供了这么多种get方法来获取 。
如果metadata 的数据类型是没办法确定的,那么可以直接使用 Object object = metaData.get(key)来获取 ,然后再转化成自己要想的数据类型。

[!--infotagslink--]

相关文章

  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
  • 深入理解Android中View和ViewGroup

    深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • Android设置TextView竖着显示实例

    TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
  • android.os.BinderProxy cannot be cast to com解决办法

    本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20
  • Android 实现钉钉自动打卡功能

    这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
  • Android 开发之布局细节对比:RTL模式

    下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
  • Android中使用SDcard进行文件的读取方法

    首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20
  • Android开发之PhoneGap打包及错误解决办法

    下面来给各位简单的介绍一下关于Android开发之PhoneGap打包及错误解决办法,希望碰到此类问题的同学可进入参考一下哦。 在我安装、配置好PhoneGap项目的所有依赖...2016-09-20
  • 用Intel HAXM给Android模拟器Emulator加速

    Android 模拟器 Emulator 速度真心不给力,, 现在我们来介绍使用 Intel HAXM 技术为 Android 模拟器加速,使模拟器运行度与真机比肩。 周末试玩了一下在Eclipse中使...2016-09-20
  • Android判断当前屏幕是全屏还是非全屏

    在安卓开发时我碰到一个问题就是需要实现全屏,但又需要我们来判断出用户是使用了全屏或非全屏了,下面我分别找了两段代码,大家可参考。 先来看一个android屏幕全屏实...2016-09-20
  • Android开发中布局中的onClick简单完成多控件时的监听的利与弊

    本文章来为各位介绍一篇关于Android开发中布局中的onClick简单完成多控件时的监听的利与弊的例子,希望这个例子能够帮助到各位朋友. 首先在一个控件加上这么一句:and...2016-09-20
  • Ubuntu 系统下安装Android开发环境 Android Studio 1.0 步骤

    Android Studio 是一个Android开发环境,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试,可以在Linux,Mac OS X,Window...2016-09-20
  • Android实现简单用户注册案例

    这篇文章主要为大家详细介绍了Android实现简单用户注册案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-26