星期日, 八月 31, 2014
星期三, 八月 27, 2014
如何在Android里使用最新的Apache Httpclient
注意:Android最早使用的Apache HttpClient 4.0-beta的一个包,后来基本 不再维护,所以如果有更多的新的HTTP 特性,基本不再支持, 而且,Android推荐大家使用系统标准的java标准包:HttpURLConnection 但是HttpURLConnection比较底层,使用起来非常的不便,尤其是在 类似提交Form和服务器传送数据的时候;所以最近有okHttp就封装了HttpURLConnction
给开发人员提供了较好的API.但是使用起来依然不如HttpRequest爽快.
尤其是在目前稍微严肃的应用都会基于HTTPS/SSL的基础之上,大量的验证 模式支持就是以前的4.0版本不支持的。没有现成的方案。所以使用 最新的httpclient包是必须的了。 但是由于httpclient是基于标准JDK的,有许多牵涉到版权的API比如
misc.sun之类的包不能在Android上使用,所以这个处理工作还是比较繁琐的。 幸运的是apache提供了Android移植包: 参考,写本文时的最新版本4.3.5: http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html
可以在www.mvnrepository.com上 输入httpclient-android来寻找最新的 jar包Android移植版本并下载即可。 当然有些类不可避免的原始的类的功能不同并有扩展,这个时候,就要使用 类名带HC4结尾的类来使用最新的功能特性了
但是如果我们在Android Activity调用Async或者Thread调用最基本的: CloseableHttpClient httpclient = HttpClients.createDefault(); 立即出现异常: java.lang.IllegalArgumentException: Item may not be null 查看代码则是: org.apache.http.config.RegistryBuilder.java 的 Args.notNull(item, "Item");造成了错误。 阅读代码发现,这是因为SocketFactory为空造成的,所以 必须首先初始化,SocketFactory SSLContext sslContext = SSLContexts.createSystemDefault(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslContext, SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER); CloseableHttpClient httpclient= HttpClientBuilder.create() .setSSLSocketFactory(sslsf) .build(); 或者使用定制的方法: ConnectionSocketFactory plainsf = <...> LayeredConnectionSocketFactory sslsf = <...> Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", plainsf) .register("https", sslsf) .build(); HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r); HttpClients.custom() .setConnectionManager(cm) .build(); 这个都可以从hc.apache.org对应版本的tutorial章节,看到详细的代码 注意在android使用需要在AndroidManifest.xml里加入权限: <uses-permission android:name="android.permission.INTERNET"/> 这个httpclient-android-4.3.5.jar在Android Studio和Eclipse ADT 里如何打包到最后的apk里步骤不同,使用的时候注意即可。
星期四, 八月 21, 2014
Button 实现淡入淡出动画
布局文件:
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.buttonana.MainActivity" >
<Button
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/animationid"
android:text="fade out"/>
<Button
android:id="@+id/mainbtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/animationid"
android:layout_alignParentTop="true"
android:layout_marginTop="170dp"
android:text="Click Me" />
</RelativeLayout>
关键语句:
amt.setFillAfter(true);//important.
package com.example.buttonana;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
public class MainActivity extends Activity {
Button mainbtn;
Button animationbtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainbtn=(Button)this.findViewById(R.id.mainbtn);
animationbtn=(Button)this.findViewById(R.id.animationid);
mainbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("BUTTON","enter.........................................................");
Animation t =getAnimation();
animationbtn.clearAnimation();
animationbtn.setAnimation(t);
t.startNow();
}
});
}
public Animation getAnimation()
{
Animation amt=new AlphaAnimation(1.0f,0.01f);
amt.setDuration(4*1000);
amt.setFillAfter(true);//important.
return amt;
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.buttonana.MainActivity" >
<Button
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/animationid"
android:text="fade out"/>
<Button
android:id="@+id/mainbtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/animationid"
android:layout_alignParentTop="true"
android:layout_marginTop="170dp"
android:text="Click Me" />
</RelativeLayout>
关键语句:
amt.setFillAfter(true);//important.
package com.example.buttonana;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
public class MainActivity extends Activity {
Button mainbtn;
Button animationbtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainbtn=(Button)this.findViewById(R.id.mainbtn);
animationbtn=(Button)this.findViewById(R.id.animationid);
mainbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("BUTTON","enter.........................................................");
Animation t =getAnimation();
animationbtn.clearAnimation();
animationbtn.setAnimation(t);
t.startNow();
}
});
}
public Animation getAnimation()
{
Animation amt=new AlphaAnimation(1.0f,0.01f);
amt.setDuration(4*1000);
amt.setFillAfter(true);//important.
return amt;
}
}
星期二, 八月 05, 2014
星期日, 八月 03, 2014
Android Studio Beta 打包源代码和build.gradle 脚本到一个zip文件
在build.gradle脚本里加入脚本:
task srcZip2(type: Zip) {
classifier = 'src'
from projectDir
include 'src/**/*'
include 'build.gradle'
destinationDir file('.')
archiveName "src.zip"
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
task.dependsOn 'srcZip2'
}
}
task srcZip2(type: Zip) {
classifier = 'src'
from projectDir
include 'src/**/*'
include 'build.gradle'
destinationDir file('.')
archiveName "src.zip"
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
task.dependsOn 'srcZip2'
}
}
最后就在当前 app目录下建立了src.zip文件。
如何在Android Studio beta 版本里加入Build versionNumber的脚本。
利用AndroidManifest.xml里的android:versionCode"整数",
android:versionName为字符串,格式为"0.0.1"的格式。
将一下代码复制到build.gradle里,最后空白的地方,sync之后即可:
这是在build project的时候,即更新AndroidManifest.xml里的
这两个字段
task('increaseVersionCode') << {
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = Integer.parseInt(matcher.group(1))
versionCode= versionCode+1
def manifestContent = matcher.replaceAll("versionCode=\"" + versionCode + "\"")
manifestFile.write(manifestContent)
println "versionCode is:"+versionCode
}
task('incrementVersionName') << {
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
def buildVersion = Integer.parseInt(matcherVersionNumber.group(3))
def mNextVersionName = majorVersion + "." + minorVersion + "." + + (buildVersion + 1)
def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
println "build number is:"+mNextVersionName
manifestFile.write(manifestContent)
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
task.dependsOn 'increaseVersionCode'
task.dependsOn 'incrementVersionName'
}
}
android:versionName为字符串,格式为"0.0.1"的格式。
将一下代码复制到build.gradle里,最后空白的地方,sync之后即可:
这是在build project的时候,即更新AndroidManifest.xml里的
这两个字段
task('increaseVersionCode') << {
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = Integer.parseInt(matcher.group(1))
versionCode= versionCode+1
def manifestContent = matcher.replaceAll("versionCode=\"" + versionCode + "\"")
manifestFile.write(manifestContent)
println "versionCode is:"+versionCode
}
task('incrementVersionName') << {
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
def buildVersion = Integer.parseInt(matcherVersionNumber.group(3))
def mNextVersionName = majorVersion + "." + minorVersion + "." + + (buildVersion + 1)
def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
println "build number is:"+mNextVersionName
manifestFile.write(manifestContent)
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
task.dependsOn 'increaseVersionCode'
task.dependsOn 'incrementVersionName'
}
}
订阅:
博文 (Atom)