Archive for the 'Android' 类别

02

Java的IO操作真是复杂,要经过以下几个步骤:
URL->HttpURLConnection->InputStream->InputStreamReader->BufferReader.readLine()
请看通用的类HttpDownloader:

package cc.ewings.download;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpDownloader {
	private URL url=null;

	//本函数近适用于文本类文件的下载
	public String download(String urlStr){
		StringBuffer sb=new StringBuffer();
		String line=null;
		BufferedReader buffer = null;
		try{
			//URL->HttpURLConnection->InputStream->InputStreamReader->BufferReader.readLine()
			url=new URL(urlStr);
			HttpURLConnection urlConn=(HttpURLConnection) url.openConnection();
			buffer = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
			while((line=buffer.readLine()) != null){
				sb.append(line);
			}
		} catch (Exception e){
			e.printStackTrace();
		} finally {
			try{
				buffer.close();
			} catch(Exception e){
				e.printStackTrace();
			}
		}

		return sb.toString();

	}
}
01

一 广播机制

1 创建一个继承自BroadReceiver的类MyReceiver:

package cc.ewings.BroadcastTest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context arg0, Intent arg1) {
		// TODO Auto-generated method stub
		System.out.println("received");
	}
}

2 在主类中广播intent

package cc.ewings.BroadcastTest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class BroadCastActivity extends Activity {
    Button myBtn;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        myBtn=(Button) this.findViewById(R.id.myBtn);
        myBtn.setOnClickListener(new MyListener());
    }

    class MyListener implements OnClickListener{

		public void onClick(View arg0) {
			// TODO Auto-generated method stub
			Intent myIntent=new Intent();
			myIntent.setAction(Intent.ACTION_EDIT);
			BroadCastActivity.this.sendBroadcast(myIntent);
		}

    }
}

3 在Manifest中注册receiver

<receiver android:name=".MyReceiver">
        <intent-filter>
            <action android:name="android.intent.action.EDIT"/>
        </intent-filter>
    </receiver>

注: 在主Activity中也可以直接注册侦听,这样就不用再Manifest注册了:

package cc.ewings.BroadcastTest;

import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class BroadCastCodeDefine extends Activity {
    Button myBtn;
    MyReceiver receiver;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        myBtn=(Button) this.findViewById(R.id.myBtn);
        myBtn.setOnClickListener(new MyListener());
        receiver=new MyReceiver();
        registerReceiver(receiver, new IntentFilter("cc.ewings.foodstar.refreshPage"));
    }

    @Override
    protected void onPause() {
        super.onPause();
         unregisterReceiver(receiver);
    }

    class MyListener implements OnClickListener{

		public void onClick(View arg0) {
			// TODO Auto-generated method stub
			System.out.println("broadcasting");
			Intent myIntent=new Intent();
			myIntent.setAction("cc.ewings.foodstar.refreshPage");
			BroadCastCodeDefine.this.sendBroadcast(myIntent);
		}

    }
}

这样的好处是,可以关闭侦听。用Manifest中注册的,则关闭程序后仍然能收到侦听。

30

伪线程(其实还是用的主线程)

1 Handler myHandler=new Handler {handleMessage(){}}定义内部匿名handler
注:super.handleMessage(msg);//注意:不能带着一句,否则报错

2 Runnable myRunnable=new Runnable(){run(){}}实现线程

3 myHandler.post(myRunnable) 开始线程,myHandler.removeCallbacks(myRunnable);终止线程

4 myHandler.postDelayed(1000) 线程推迟执行

5 Thread.sleep(1000) 在run()里暂停线程

6 在Run里传递参数给handler,hanler里的handleMessage会接收到消息,也可以在其中再次开始线程。
Message msg=myHandler.obtainMessage();
msg.arg1=progress;
myHandler.sendMessage(msg);

真线程

用HandlerThread.getLooper()给继承自Handler的MyHandler,这样就可以开始一个新的线程了。MyHandler要起到两个作用:1 把looper传给父级;2 重写handleMessage来加上自己的逻辑

package cc.ewings.handlerTest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.widget.Toast;

public class LooperAndBoundle extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		HandlerThread handlerThread=new HandlerThread("my thread");
		handlerThread.start();
		MyHandler myHandler=new MyHandler(handlerThread.getLooper());
		Message msg=myHandler.obtainMessage();
		Bundle b=new Bundle();
		b.putString("name", "zhangsan");
		b.putInt("age", 30);
		msg.setData(b);
		msg.sendToTarget();
	}	

	class MyHandler extends Handler{
		public MyHandler(Looper looper){
			super(looper);
		}
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			//super.handleMessage(msg);
			Bundle data=msg.getData();
			String name=(String) data.getString("name");
			int age=(int) data.getInt("age");
			Toast.makeText(LooperAndBoundle.this, "name: "+name+" age:"+age, Toast.LENGTH_LONG).show();
		}

	};
}
12

android开发接近尾声时需要打包apk,如果想sign,那就要生成一个keystore文件。但出现java.io.filenotfoundexception错误.

后来发现是因为jdk安装在了c盘,系统有保护,不让生成文件。于是把jdk挪到D盘,再用命令: keytool -genkey -alias android.keystore -keyalg RSA -validity 100000 -keystore android.keystore

一步一步按提示来,果然成功生成了keystore文件。Oh yeah!

21

在借鉴别人实例文件时,经常需要修改包名。这里介绍下在Eclipse下怎么修改包名:

1 项目名称上右键/Android Tools/Rename Application Package

2 在包上右键/Refactor/Rename
此处如果选中Rename subpackages和Update texual occurences in comments….则可以快速深入修改多个包,但也可能会导致manifest文件出点小问题。

3 批量查找原有包名
我习惯用dreameaver的查找功能,很好用,很彻底。

4 如果产生了多个R文件,删除原有的

5  清理项目文件
Project/Clean

09

List是比复杂的一个控件,主要复杂在是适配器(Adapter)的构建,它需要一个List、一个单独的View和另外一些参数。
下面是一个例子:
main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<ListView
	android:id="@id/android:list"
	android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:drawSelectorOnTop="false"
    android:scrollbars="vertical"
/>
</LinearLayout>

list.xml,注意设置LinearLayout的格式,不然会很难看

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="5dip"
    >
<TextView
	android:id="@+id/user_name"
	android:layout_width="150dip"
    android:layout_height="30dip"
    android:singleLine="true"
    android:textSize="10pt"
/>
<TextView
	android:id="@+id/user_ip"
	android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textSize="10pt"
/>
</LinearLayout>

主程序,注意继承的是ListActivity而不是Activity

package cc.ewings.test;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class ListTest extends ListActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ArrayList> list = new ArrayList>();
        HashMap map1=new HashMap();
        HashMap map2=new HashMap();
        HashMap map3=new HashMap();
        map1.put("user_name", "adam");
        map1.put("user_ip","192.168.0.1");
        map2.put("user_name", "eva");
        map2.put("user_ip","192.168.0.2");
        map3.put("user_name", "yoyo");
        map3.put("user_ip","192.168.0.3");
        list.add(map1);
        list.add(map2);
        list.add(map3);
        SimpleAdapter adapter=new SimpleAdapter(this,list,R.layout.list,new String[]{"user_name","user_ip"},new int[]{R.id.user_name,R.id.user_ip});
        this.setListAdapter(adapter);
    }

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		// TODO Auto-generated method stub
		super.onListItemClick(l, v, position, id);
		Toast.makeText(this,"position="+position, Toast.LENGTH_SHORT).show();
	}
}
07

ProgressBar分为两种,由style来区分,style的写法是在太奇怪了,估计用20便也记不住:
<ProgressBar android:id="@+id/bar1" android:layout_width="fill_parent" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal" android:visibility="gone" /> <ProgressBar android:id="@+id/bar2" android:layout_width="wrap_content" android:layout_height="wrap_content" style="?android:attr/progressBarStyle" android:visibility="gone" />
下面是一段简单的progressBar使用示例

class clickListener implements OnClickListener{
		public void onClick(View v) {
			// TODO Auto-generated method stub
			if(i==0){
				bar1.setVisibility(View.VISIBLE);
				bar2.setVisibility(View.VISIBLE);
			} else if(i
				
07

在XX之上/下/左/右
android:layout-above
android:layout-below
android:layout-toLeftOf
android:layout-toRightOf

与XX 基线/底/左/右/顶对齐
android:layout-alignBaseline
android:layout-alignBottom
android:layout-alignLeft
android:layout-alignRight
android:layout-alignTop

如果值为true,那么与父控件底/左/右/顶对齐
android:layout-alignParentBottom
android:layout-alignParentLeft
android:layout-alignParentRight
android:layout-alignParentTop

如果值为true,那么居中
android:layout-centerHorizental
android:layout-centerInParent
android:layout-centerVertical

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Please input" android:id="@+id/label" /> <EditText android:id="@+id/input" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@id/label" /> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="OK" android:layout_below="@id/input" android:layout_alignParentRight="true" /> <Button android:id="@+id/cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel" android:layout_below="@id/input" android:layout_toLeftOf="@id/ok" /> </RelativeLayout>