当前位置:  编程技术>移动开发
本页文章导读:
    ▪对单个资料取消ARC        对单个文件取消ARC 请直接看 StakeOverlow  http://stackoverflow.com/questions/6646052/how-can-i-disable-arc-for-a-single-file-in-a-project/6658549#6658549  ......
    ▪ 屉子效果——抄来的,感觉不错        抽屉效果——抄来的,感觉不错 抽屉效果的控件在Android里也就是SlidingDrawer,当时讨论需要的是一个可控弹出高度的效果。通过朋友的一段DEMO的基础上进行了一些改动,完成了一个比较简.........
    ▪ 单例模式-惟独一个实例       单例模式--只有一个实例 什么是单例模式:     确保一个类只有一个实例,并提供一个全局访问点。 注意:使用起来类似静态方法,但是它不是静态方法,而是类。需要new关键字来实例化。.........

[1]对单个资料取消ARC
    来源: 互联网  发布时间: 2014-02-18
对单个文件取消ARC

请直接看 StakeOverlow  http://stackoverflow.com/questions/6646052/how-can-i-disable-arc-for-a-single-file-in-a-project/6658549#6658549 


    
[2] 屉子效果——抄来的,感觉不错
    来源: 互联网  发布时间: 2014-02-18
抽屉效果——抄来的,感觉不错
抽屉效果的控件在Android里也就是SlidingDrawer,当时讨论需要的是一个可控弹出高度的效果。

通过朋友的一段DEMO的基础上进行了一些改动,完成了一个比较简陋的效果,

由于只是个小DEMO所以有些代码不规范的地方,大家体谅,并可自行修改。测试环境2.1下运行正常,

附上截图若干:







首先自定义一个抽屉控件

package org.widget.drawer;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.SlidingDrawer;



public class TempSlidingDrawer extends SlidingDrawer {
    private boolean mVertical;
    private int mTopOffset;


public TempSlidingDrawer(Context context, AttributeSet attrs) {
        super(context, attrs);
        int orientation = attrs.getAttributeIntValue("android", "orientation", ORIENTATION_VERTICAL);
        mTopOffset = attrs.getAttributeIntValue("android", "topOffset", 0);
        mVertical = (orientation == SlidingDrawer.ORIENTATION_VERTICAL);
    }

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize =  MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize =  MeasureSpec.getSize(heightMeasureSpec);

final View handle = getHandle();
        final View content = getContent();
        measureChild(handle, widthMeasureSpec, heightMeasureSpec);

if (mVertical) {
            int height = heightSpecSize - handle.getMeasuredHeight() - mTopOffset;
            content.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, heightSpecMode));
            heightSpecSize = handle.getMeasuredHeight() + mTopOffset + content.getMeasuredHeight();
            widthSpecSize = content.getMeasuredWidth();
            if (handle.getMeasuredWidth() > widthSpecSize) widthSpecSize = handle.getMeasuredWidth();
        }
        else {
            int width = widthSpecSize - handle.getMeasuredWidth() - mTopOffset;
            getContent().measure(MeasureSpec.makeMeasureSpec(width, widthSpecMode), heightMeasureSpec);
            widthSpecSize = handle.getMeasuredWidth() + mTopOffset + content.getMeasuredWidth();
            heightSpecSize = content.getMeasuredHeight();
            if (handle.getMeasuredHeight() > heightSpecSize) heightSpecSize = handle.getMeasuredHeight();
        }

setMeasuredDimension(widthSpecSize, heightSpecSize);
    }
}



然后在需要的布局文件里添加该自定义控件:(布局可以根据自己的需求自己修改部分)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<org.widget.drawer.TempSlidingDrawer
  android:id="@+id/slidingDrawer1" android:layout_width="fill_parent"
  android:layout_height="wrap_content" android:allowSingleTap="true"
  android:animateOnClick="true" android:content="@+id/content"
  android:handle="@+id/handle" android:orientation="vertical"
  android:background="#000000"
  android:layout_alignParentBottom="true">

  <Button android:id="@+id/handle" android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:background="@drawable/btn_menu_top" />

  <LinearLayout android:id="@+id/content" android:background="#0000AA"
   android:layout_width="wrap_content" android:layout_height="wrap_content">

   <TextView android:id="@+id/textView1" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TestTestTest\nTestTestTest\nTestTest\nTestTestTestTest\nTestTestTest\nTestTest\nTest" />
  </LinearLayout>
</org.widget.drawer.TempSlidingDrawer>

</RelativeLayout>



在Activity里的代码如下部分

package org.widget.drawer;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.Button;
import android.widget.SlidingDrawer.OnDrawerCloseListener;
import android.widget.SlidingDrawer.OnDrawerOpenListener;
import android.widget.SlidingDrawer.OnDrawerScrollListener;

public class MainActivity extends Activity {

private Button btn_drawer;//抽屉的按钮
private TempSlidingDrawer mDrawer;
private Boolean flag = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
      
        initDrawer();
    }

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
  
    private void initDrawer() {
  // TODO Auto-generated method stub
  btn_drawer = (Button) findViewById(R.id.handle);
  mDrawer = (TempSlidingDrawer) findViewById(R.id.slidingDrawer1);

mDrawer.setOnDrawerOpenListener(new OnDrawerOpenListener() {

public void onDrawerOpened() {

// TODO Auto-generated method stub
    flag = true;
    btn_drawer.setBackgroundResource(R.drawable.btn_menu_top);
   }
  });

mDrawer.setOnDrawerCloseListener(new OnDrawerCloseListener() {

public void onDrawerClosed() {

// TODO Auto-generated method stub
    flag = false;
    btn_drawer.setBackgroundResource(R.drawable.btn_menu_top);
   }
  });

mDrawer.setOnDrawerScrollListener(new OnDrawerScrollListener() {

public void onScrollStarted() {
    // TODO Auto-generated method stub

}

public void onScrollEnded() {
    // TODO Auto-generated method stub

}
  });
}
}




    
[3] 单例模式-惟独一个实例
    来源: 互联网  发布时间: 2014-02-18
单例模式--只有一个实例

什么是单例模式:

 

 

确保一个类只有一个实例,并提供一个全局访问点。

注意:使用起来类似静态方法,但是它不是静态方法,而是类。需要new关键字来实例化。

 

 

单例模式的基本使用方式可以概括为3个步骤:

1.创建一个private静态变量;

2.创建一个private空构造器;

3.创建一个public静态访问点,用来将唯一实例返回给外部调用者。

 

基本使用方式:

 

方法1:

public class SingletonCommon {

	private static SingletonCommon uniqueInstance;//步骤一
	
	private SingletonCommon(){}//步骤二
	
	public static SingletonCommon getInstance()//步骤三
	{
		if(uniqueInstance == null)
		{
			uniqueInstance = new SingletonCommon();
		}
		return uniqueInstance;
	}
}
 

虽然看上去简单。但是这个类还存在问题。

我们的程序基本都是多线程的。就存在这样的可能:多个线程同时去调用这个实例,假设这个时候uniqueInstance == null,而线程A执行到if(uniqueInstance == null)这句语句,这时候系统线程调度,线程A交出cpu。转而执行B线程中的代码,而在B线程中也有可能访问这个类,那么它访问的时候,发现uniqueInstance == null,自然就创建一个实例。等到cpu的使用权回到A的时候,A从刚才停住的地方开始执行,也创建了一个实例!所以这个时候问题就出现了。

 

那么怎么解决这个问题呢?

 

方法:2:

 

使用synchronized关键字

通过这个关键字可以迫使线程在进入这个方法前,要等别的线程离开这个方法,这样就可以不会有两个线程同时访问这个类了,我们的问题就解决了。而且使用起来很简单,仅仅多了一个synchronized关键字而已。

 

public class SingletonSynchronized {

	private static SingletonSynchronized uniqueInstance;
	
	private SingletonSynchronized(){}
	
	public static synchronized SingletonSynchronized getInstance()
	{
		if(uniqueInstance == null)
		{
			uniqueInstance = new SingletonSynchronized();
		}
		return uniqueInstance;
	}
}
 

但是这样也存在一个问题:效率。

每次调用getInstance()的时候都要进行同步,会造成负担。

那么怎么办才能提高效率呢?

 

方法3:

使用 双重检查加锁

 

利用双重检查加锁,首先检查是否已经创建了实例,如果还没有创建,才进行同步

这样一来就只有第一次会同步。这样就可以提高效率。

 

这里需要引入volatile关键字,这个关键字确保当uniqueInstance变量被初始化成SingletonDoubleLocking实例时,

多个线程正确地处理uniqueInstance变量。

 

public class SingletonDoubleLocking {

	private volatile static SingletonDoubleLocking uniqueInstance;
	
	private SingletonDoubleLocking(){}
	
	public static SingletonDoubleLocking getInstance()
	{
		if(uniqueInstance == null)
		{
			synchronized (SingletonDoubleLocking.class) 
			{
				if(uniqueInstance == null)
				{
					uniqueInstance = new SingletonDoubleLocking();
				}
			}
		}
		return uniqueInstance;
	}
}
 

这样做似乎已经无懈可击了。但是还有问题存在!

问题是:双重检查加锁不适用于1.4及更早版本的Java

 

那还有别的方法吗?

我们知道前面的做法主要都是为了围绕着如何避免产生多个单例。

那能不能在调用getInstance()之前就生成实例呢?这样不就避免了所有的问题了吗?

 

方法4:

急切创建实例

 

在虚拟机加载这个类的时候就马上创建单例,这样就确保了在任何线程访问这个变量的时候,该实例都已经存在了。

 

public class SingletonEagerly {

	private static SingletonEagerly uniqueInstance = new SingletonEagerly();//虚拟机加载这个类的时候,这个类就已经被创建
	
	private SingletonEagerly(){}
	
	public static SingletonEagerly getInstance()
	{
		return uniqueInstance;//不需要判断是否为null,直接返回就可以了
	}
}

 

 

 

 

总结:

 

方法1:最普通的单例,建议不要这样使用,以免出问题。

 

方法2:使用synchronized关键字,使得每个线程进入这个方法之前,要等候别的线程离开这个方法才进入。对程序性能要求不高的的情况下可以使用,仅仅比普通的单例模式多了一个关键字而已。

 

方法3:双重检查加锁法,使用volatile关键字,它确保了变量被初始化为实例时,多个线程能够正确地处理变量。这是个不错的选择,但是要注意不能用于java1.4及之前的java版本。在Android中是可以选择这样做的,因为一般我们选择的jdk都是1.5及以上的。

 

方法4:急切创建实例法,如果这个类的不大,负担不重,那么可以考虑直接在JVM加载的这个类的时候,直接就生成实例。

 

 

 

我将上面4种方法,写成一个Android上可以运行的demo,demo中有两个Activity,在这两个Activity中通过单例的调用方式都将单例的的地址打印出来。我们可以看见,它们在内存中的物理地址一样,则表明它们是同一个对象。

如图所示:

 

 

 

 

 

 

 

有兴趣的同学可以下载来看看:

 

https://github.com/michaelye/SingletonPattern

 

 

 

 

 

 

 

 


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android中通过view方式获取当前Activity的屏幕截... iis7站长之家
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪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