一.
对与java读写文件的操作:
字节流:
//filename 可以是文件名,可以是文件路径
FileOutputStream outputStream=new FileOutputStream(filename);
//filename 可以是文件名,可以是文件路径
//append 是否追加
FileOutputStream outputStream=new FileOutputStream(filename,bool append);
outputStream.write(byte[]);
outputStream.close();
//filename 文件名或文件路径
FileInputStream inputStream=new FileInputStream(filename);
Byte[] buffer=new byte[1024];//缓存数组;
//inputStream.read(buffer);//返回值是int型;
读的时候要先把这些数据放入内存中或者是一个FileOutputStream流中
//FileOutputStream outputStream=new FileOutputStream(filename);
ByteArrayOutpouStream outputStream=new ByteArrayOutputStream();
Int len=0;
While((len=inputStream.read(buffer))!=-1)
{
outputStream.write(buffer,0,len);
}
二.
<?xml version=”1.0” encoding=”UTF-8”>
<persons>
<person id=”1”>
<name>wanghe</name>
<age>20</age>
</person>
</persons>
对于使用Pull解析器来解析XML
List<Person> persons=null;
Person person=null;
File file=new File(filename);
FileinputStream input=new FileInputStream(file);
XmlPullParser pullParser=XML.newPullParser();
pullParser.setInput(input,”UTF-8”);
Int event=pullParser.getEventType();
While(event!=XmlPullParser.END_DOCUMENT)
{
Switch(event)
{
Case XmlPullParser.START_DOCUMENT:
Persons=new ArrayList<Person>();
Break;
Case XmlPullParser.START_TAG
If(“person”.equal(pullParser.getName()))
{
Person=new Person();
String id=pullParser.getAttributeValue(0);
person.setId(id);
}
Else if(“name”.equal(pullParser.getName()))
{
String name=pullParser.nextText();
person.setName(name);
}
Else if(“age”.equal(pullParser.getName()))
{
String age=pullParser.nextText();
person.setAge(age);
}
Break;
Case XmlPullParser.END_TAG:
If(“person”.equal(pullParser.getName()))
{
Persons.add(person);
Person=null;
}
}
Event=pullParser.next();
}
Return persons;
对与保存一个XML
File file=new File(filename)
FileOutputStream out=new FileOutputStream(file);
XmlSerializer ser=XML.newXmlSerializer();
Ser.setOutput(out,”UTF-8”);
ser.startDocument(“UTF-8”,true);
ser.srartTag(null,”persons”)//第一个参数是namespace 第二个是节点名称
For(Person person:persons)
{
er.startTag(null, "person");
ser.attribute(null, "id", person.getId());
ser.startTag(null, "name");
ser.text(person.getName());
ser.endTag(null,"name");
ser.startTag(null, "age");
ser.text(person.getAge());
ser.endTag(null,"age");
ser.endTag(null, "person");
}
ser.endTag();
ser.endDocument();
Out.flush();
Out.close();
三.sharedPreferences
对于sharedPrefernces是对用户数据的一个自定义保存数据
比如每次等qq不用自己再输入帐号和密码而是从以前输入的数据存储后再调出
SharedPreferences share=context.getSharedPreferences("ifo",Context.MODE_PRIVATE);//参数一是对xml文件名的定义,参数二是对此文件的权限定义,context是上下文的意思,如getApplicationContext()等等;
Editor editor=share.edit();
editor.putString(“key”,”value”);
Editor.commit();
对于怎么取出数据就是;
SharedPreferences share=context.getSharedPreferences("ifo",Context.MODE_PRIVATE);
String value=share.getString(“key”,”defaultvalue”);//根据key来取值,那个defaultvalue是默认取到的值;
四.SQLiteDatabase
对与SQLite,他要实现SQLiteOpenHelper虚拟类
定义MySQLiteOpenHelper:
Class MySQLiteOpenHelper:SQLiteOpenHelper
{
//实现一个构造函数
Public MySQLiteOpenHelper(Context context)
{
//context 定义上下文
//databaseName 定义数据库名字
//CursorFactory 定义游标工厂,默认为null,使用系统的
//version 版本号,version>0 当version改变时会调用onUpgrade方法
Super(context,databaseNAME,CursoeFactory,version)
}
//实现两个方法
public void onCreate(SQLiteDatabase db) //在第一次调用是使用,可以加入多个execSQL()方法
{
// TODO Auto-generated method stub
db.execSQL("create table person (name text ,age text)");//定义一个表;
//为表初始化数据
//db.execSQL("insert into person(name,age)values (?,?)",new String[]{“wanghe”,”20”});
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2)//当版本号改变是执行 {
// TODO Auto-generated method stub
//当version版本号改变时;
db.execSQL("alert table person add phone text");
}
}
定义SQLiteServer实现数据库方法
Class SQLiteServer
{
Private MySQLiteOpenHelper mySQL;
Public SQLiteServer (Context context)
{
mySQL=new MySQLiteOpenHelper(context);
}
//查询
Public Cursor select(String name)
{
SQLiteDatabase db=mySQL.getReadableDatabase();
Cursor cursor=db.rawQuery(“select * from person where name=?”,new String[]{name});
Db.close();
Return cursor;
}
//实现分页效果,offset是开始,maxdata是查寻个数
Public Cursor selectLimit(int offset,int maxdata)
{
SQLiteDatabase db=mySQL.getReadableDatabase();
Cursor cursor=db.rawQuery(“select * from person limit ?,?” ,new String[]{String.valueof(offset),String.valueof(maxdata)});
Db.close();
Return cursor;
}
//插入
Public void insert(Person person)
{
SQLiteDatabase db=mySQL.getWriteableDatabase();
db.execSQL(“insert into person(name.age) values(?,?)”,new Object[]{person.getName(),person.getAge()}); }
//更新
Public void update(Person person)
{
SQLiteDatabase db=mySQL.getWriteableDatabase();
db.execSQL(“update person set age=? Where name=?”,new Object[]{person.getName(),person.getAge()});
Db.close();
}
//删除
Public void delete(String name)
{
SQLiteDatabase db=mySQL.getWriteableDatabase();
db.execSQL(“delete form person where name=?”,new Object[]{name});
db.close();
}
//获取查询的个数
Public long getCount()
{
SQLiteDatabase db=mySQL.getReadableDatabase();
Cursor cursor=db.rawQuery(“select count(*) from person “,null);
//由于只会出现一条记录
cursor.moveToFirst();
Long count=cursor.getLong(0);
Db.close();
Return count;
}
}
对伊Cursor这个类,里面的api
Cursor cursor;
如果查询结果是多个,则用cursro.moveToNext()这个方法
While(cursor.moveToNext())
{
//怎么获取记录,cursor.getColumnIndex(“name“)这个方法是获取name属性的下标
String name=cursor.getString(cursor.getColumnIndex(“name”));
}
对于SQLite的并发控制
Public void SqlCommit()
{
SQLiteDatabase db=mySQL.getWriteableDatabase();
db.beginTransaction();
Try
{
db.execSQL(“........”);
db.execSQL(“..........”);
db.setTransactionSuccessful();//如果不使用次api就只会回滚,不会提交
}
Finally{
db.endTransaction();
}
}
五.ListView及各Adapter
对与ListView的使用要用到各种构造器;
SimpleAdapter:
Class Person
{
Public String name;
Public String age;
}
List<Person>persons=new ArrayList<Person>();
List<HashMap<String,String>>listMap=new List<HashMap<String,String>>();
For(Person person:persons)
{
Map<String ,String>map=new HashMap<String,String>();
Map.put(“name”,person.name);
Map.put(“age”,person.age);
listMap.add(map);
}
SimpleAdapter adapter=new SimpleAdapter(Context context,listMap,R.layout.xml,new String[]{“name”,”age”},new int[]{R.id.txtname,R.is.txtage});
list.setAdapter(adapter);//第一个参宿是上下文context,第二个参数是List<HashMap<String,String>>
第三个参数是,布局layout,第四个是HashMap里的key字符串数组,第五个是布局里的R.id数组;
对于怎么取到这样构造的形式的数据
OnItemClick(AdapterView<?> parent, View view, int position,long id)
{
//因为存入的是HashMap,则在取时也应是hashmap
HashMap<String,String>map=HasnMap<String,String>parent.getItemPosition(position);
String name=map.get(“name”);
String age=map.get(“age”);
}
第二种构造器就是SimpleCursorAdapter,此方法感觉就是重在去SQLite里的Cursor
因为在SQLite里有Cursor cursor=db.rawQuery(“”,null);
SimpleCursorAdapter adapter=new SimpleCursorAdapter(Context,R.layout.xml,cursor,new String[]{“name”,”age”},new int[]{R.id.txtname,R.id.txtage});
list.setAdapter(adapter);
对于这种的取数据,当然要用到Cursor
OnItemClick(AdapterView<?> parent, View view, int position,long id)
{
Cursorcursor=(Cursor)parent.getItemPosition(position);
String name=cursor.getString(cursor.getColumnIndex(“name”));
String age=cursor.getString(cursor.getColumnIndex(“n\age”));
}
第三种就是自己写构造器,继承BaseAdapter
Class PersonAdapter implements BaseAdapter
{
Private List<Person> persons;//传入的List
Private int Resouce;//传入自定义布局
Private LayoutInflater inflater;//构造一个View
public PersonAdapter(Context context,List<Person> persons,int resource)
{
this.persons=persons;
this.Resource=resource;
inflater=(LayoutInflater)ontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return persons.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return persons.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
对伊getView这个方法,有两种,一个效率高,一个效率低
@Override
public View getView(int position, View view, ViewGroup arg2) {
// TODO Auto-generated method stub
TextView txtname=null;
TextView txtage=null;
If(view==null)
{
View=inflater.inflate(this.Resource,null);
}
Txtname=(TextView)view.findViewById(R.id.txtname);
Txtage=(TextView)view.findViewById(R.id.txtage);
Person person=persons.get(position);
txtname.setText(person.name);
txtage.setText(person.age);
Return view;
}
//第二种getView
@Override
public View getView(int position, View view, ViewGroup arg2) {
// TODO Auto-generated method stub
TextView txtname=null;
TextView txtage=null;
If(view==null)
{
View=inflater.inflater(Resouce,null);
CacheView cache=new CacheView();
Txtname=(TextView)view.findViewById(R.id.txtname);
Txtage=(TextView)view.findViewById(R.id.txtage);
Cache.txtname=txtname;
Cache.txtage=txtage;
view.setTag(cache);
}
Else
{
CacheView cache=(CacheView)view.getTag();
Txtname=cache.txtname;
Txtage=cache.txtage;
}
Person person=persons.get(position);
txtname.setText(person.name);
txtage.setText(perosn.age);
Return view;
}
Private final class CacheView
{
Public TextView txtname;
Public TextView txtage;
}
}
对于这样的取就简单了
OnItemClick(AdapterView<?> parent, View view, int position,long id)
{
Person Person=(Person) parent.getItemAtPosition(position);
String name=person.name;
String age=person.age;
}
六.ContentProvider
为别的应用提供数据源
继承ContentProvider类
public class TestProvider extends ContentProvider {
//定义一个全局的变量UriMatcher
private UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);
//定义三个标识变量
private final static int PERSON =1;
private final static int STUDENT=2;
private final static int PERSONID=0;
//为了取得数据库所以调用自己定义的SQLiteOpenHelper
private OPSQLHelper SQLHelper=null;
//相当与构造函数
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
SQLHelper=new OPSQLHelper(getContext());
matcher.addURI("com.example.dbprovider.prodiver", "person", PERSON);//添加person的匹配,如果匹配则返回PERSON
matcher.addURI("com.example.dbprovider.prodiver", "student", STUDENT);//添加student的匹配,如果匹配则返回STUDENT
matcher.addURI("com.example.dbprovider.prodiver", "person/#", PERSONID);//添加person/id的匹配,如果匹配则返回PERSONID
return true;
}
@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
String arg4) {
// TODO Auto-generated method stub
SQLiteDatabase db=SQLHelper.getReadableDatabase();
//可以通过判断传入的Uri来确定去操作哪个表
switch(matcher.match(arg0))
{
case PERSONID:
long id=ContentUris.parseId(arg0);//这个方法可以解析出id的值;
if(arg2==null)
{
arg2="id="+id;
}
else
{
arg2+="and id="+id;
}
case PERSON:
return db.query("person", arg1, arg2, arg3, null, null, arg4);
case STUDENT:
default:
throw Exception ;
break;
}
return null;
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri arg0, ContentValues arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
// TODO Auto-generated method stub
return 0;
}
}
怎么调用Provider提供的方法:
Uri uri=Uri.parse(“”);
ContentReslover reslover=this.getContentReslover();
Reslover.query(uri,,,,,);
Reslover.insert(uri,,);
......
对于ContentProvider要进行监听事件,包括两方面,一个是注册一个监听观察者,一个是要有一个发布者,当观察者观察到发布者发布改变消息后,就做出反应;
下面一个例子,当插入一个数据后,然后发布者发布一个消息,观察者收到做出反应
发布者:
getContext().getContentResover().notifyChange(Uri,ContentObserver);发布一条改变消息
观察者:
this.getContentResolver().registerContentObserver(Uri, true, new ContentObserver1());
Class ContentObserver extends ContentObserver
{
public ContentObserver1() {
super(new Handler());
// TODO Auto-generated constructor stub
}
@Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
//Do something
}
}
七.网络服务
获取网页内容:
URL url=new URL(“http://www.baidu.com”);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode()==200)
{
InputStream is=conn.getInputStream();
ByteArrayOutputStream os=new ByteArrayOutputStream();
byte[] buff=new byte[1024];
Int len=0;
While((len=is.read(buff))!=-1)
{
Os.write(buff,0,len);
}
String str=os.toString();
Is.close();
Os.close();
获取网页图片
URL url;
try {
url = new URL(urlPath);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode()==200)
{
InputStream is=conn.getInputStream();
Bitmap bit=BitmapFactory.decodeStream(is);
img.setImageBitmap(bit);
}
Intent
对与intent,常用来激活下一个activity,
常用的方法就是:
Intent intent=new Intent(this,newActivity.class);
对于传数据,有以下几种方式:
第一种:
放数据:
Intent intent=new Intent(MainActivity.this,NextActivity.class);
intent.putExtra("name", "王贺");
intent.putExtra("age", 21);
startActivity(intent);
取数据:
Intent intent=getIntent();
String name=intent.getStringExtra("name");
int age=intent.getIntExtra("age",0);
Toast.makeText(getApplicationContext(), name+" "+age, 1).show();
第二种:
放数据:
Intent intent=new Intent(MainActivity.this,NextActivity.class);
Bundle bun=new Bundle();
bun.putString("name", "王贺");
bun.putInt("age", 21);
intent.putExtras(bun);
startActivity(intent);
取数据:
Intent intent=getIntent();
Bundle bun=intent.getExtras();
String name=bun.getString("name");
int age=bun.getInt("age");
Toast.makeText(getApplicationContext(), name+" "+age, 1).show();
第三种:传递对象:
要对对象类进行封装:
public class Person implements Parcelable{
private int id ;
private String name;
private int age;
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
//把数据写入到Parcel对象
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeInt(id);
dest.writeString(name);
dest.writeInt(age);
}
public static final Parcelable.Creator<Person> CREATOR
= new Parcelable.Creator<Person>() {
//从Parcel对象里面读取数据
public Person createFromParcel(Parcel in) {
return new Person(in);
}
public Person[] newArray(int size) {
return new Person[size];
}
};
public Person(Parcel in) {
// TODO Auto-generated constructor stub
id = in.readInt();
name = in.readString();
age = in.readInt();
}
public Person(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
放数据:
Intent intent=new Intent(MainActivity.this,NextActivity.class);
Person person=new Person(1,"wanghe",20);
intent.putExtra("person", person);
startActivity(intent);
取数据:
Intent intent=getIntent();
Person person=intent.getParcelableExtra("person");
关于Intent之startActivityForResult
代码:
Intent intent=new Intent(this,NextActivity.class);
//参数:意图,请求码
startActivityForResult(intent,100);
要重写protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==100)
If(data!=null)
{
Toast.makeText(getApplicationContext(), data.getStringExtra("name"), 1).show();
}
}
NextActivity:
Intent intent=new Intent();
intent.putExtra("name", name);
//参数 结果码,意图
setResult(200, intent);
finish();
线程
当要访问的数据使反应的时间特别长,如获取网页数据,传输的文件等,就要用到线程
线程就要用到Handler这个中间类来链接主进程和线程的联系:
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Switch(msg.what)
{
Case 1:
Msg.obj//获取消息内容,
//dosomething
Case 2:
}
}
};
New Thread(){
Public void run(){
Message msg=new Message();
Msg.what=1;//因为可能有多个消息,所以msg.what标识一唯一消息标识
Msg.obj=””;//msg.obj发送消息的内容
handler.sendMessage(msg);//发送信息
}
}.start();
Dialog
简单对话框:
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("简单对话框");
builder.setMessage("确定吗");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}
});
AlertDialog dialog=builder.create();
dialog.show();
单选对话框:
final String[] items=new String[]{"JAVA","PHP","ASP"};
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("单选对话框");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), items[arg1], 0).show();
}
});
AlertDialog dialog=builder.create();
dialog.show();
多选对话框:
final String[] items = new String[]{"java","C#","php"};
final boolean[] checkedItems=new boolean[]{false,false,false};
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("选择");
builder.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
}
});
builder.setPositiveButton("确定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
for(int i=0;i<items.length;i++)
{
if(checkedItems[i]==true)
{
str+=items[i];
}
}
Toast.makeText(getApplicationContext(), str, 1).show();
}
});
AlertDialog dialog=builder.create();
dialog.show();
自定义对话框:
LayoutInflater infalter = LayoutInflater.from(this);;
View view=infalter.inflate(R.layout.item,null);
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("hh");
builder.setView(view);
AlertDialog dialog=builder.create();
dialog.show();
Broadcast
对于BroadcastReceiver
对于拦截短信:
Xml配置
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<receiver android:name=".SmsBroadCast">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
代码:
public class SmsBroadCast extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
Log.i("i", "拦截到短信");
Bundle bundle=arg1.getExtras();
Object[] objects=(Object[]) bundle.get("pdus");//接收一个key=pdus
for(Object object:objects)
{
SmsMessage message=SmsMessage.createFromPdu((byte[]) object);
String address=message.getDisplayOriginatingAddress();
String body=message.getDisplayMessageBody();
long date=message.getTimestampMillis();
SimpleDateFormat formater=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String formatDate=formater.format(date);
Log.i("i", address+" "+body+" "+formatDate);
abortBroadcast();
}
}
}
外拨电话:
Xml配置:
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<receiver android:name=".PhoneBroadCast">
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
代码:
public class PhoneBroadCast extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
String num=getResultData();//得到号码
setResultData("");//设置号码
Log.i("i", num);
}
}
自定义广播
自定义发送:
Intent intent=new Intent();
intent.setAction("cn.mydefine.broadcase");
intent.putExtra("msg", txt.getText().toString());
sendBroadcast(intent);
Xml配置:
<receiver android:name=".CustomRec">
<intent-filter>
<action android:name="cn.mydefine.broadcase"/>
</intent-filter>
</receiver>
接收广播:
public class CustomRec extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
String msg=arg1.getStringExtra("msg");
Log.i("msg", msg);
}
}
服务 Service
服务需要手动打开:
例:
打开服务:
Intent intent=new Intent(this,PhoneService.class);
startService(intent);
服务代码:监听电话状态:
public class PhoneService extends Service {
private TelephonyManager tm;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
tm=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(new PhoneStateListener1(), PhoneStateListener.LISTEN_CALL_STATE);
}
private final class PhoneStateListener1 extends PhoneStateListener
{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
super.onCallStateChanged(state, incomingNumber);
Log.i("电话号码:", incomingNumber+"");
switch(state)
{
case TelephonyManager.CALL_STATE_IDLE:
Log.i("i:", "无状态");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.i("i:", "接听状态");
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.i("i:", "响铃状态");
break;
}
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
Xml配置:
<service android:name=".PhoneService"></service>
访问本地自定义服务
<service android:name=".StudentService"></service>
1.绑定服务:Intent intent=new Intent(this,StudentService.class);
//bindService三个参数,意图,服务连接ServiceConnection,还有自动链接字段
bindService(intent, conn, Context.BIND_AUTO_CREATE);
2.继承ServiceConnection借口,重写ServiceConnection
private class MyServiceConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
// TODO Auto-generated method stub
//返回值是IBinder接口,所以转换为iStudentService接口来查询
iStudentService=(IStudentService) arg1;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
conn=null;
iStudentService=null;
}
}
@Override
//释放链接
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unbindService(conn);
}
3.定义接口:
public interface IStudentService {
public Student getStudent(int no);
}
4.写服务:
public class StudentService extends Service {
private final Student[] students=new Student[]{new Student(1,"王贺",20),new Student(2,"黎明",22),new Student(3,"线路",23)};
private QueryStudent queryStudent=null;
@Override
//返回值是IBinder,所以QueryStudent继承Binder和IstudentService
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
queryStudent=new QueryStudent();
return queryStudent;
}
public final class QueryStudent extends Binder implements IStudentService
{
@Override
public Student getStudent(int no) {
// TODO Auto-generated method stub
return query(no);
}
public Student query(int no)
{
return students[no-1];
}
}
}
两个应用之间的服务通信;要用到dial文件;在传输对象时,对象要继承Parcelable
服务端代码:
Student.java
package domin;
import android.os.Parcel;
import android.os.Parcelable;
public class Student implements Parcelable {
private int no;
private String name;
private int age;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel arg0, int arg1) {
// TODO Auto-generated method stub
arg0.writeInt(no);
arg0.writeString(name);
arg0.writeInt(age);
}
public static final Parcelable.Creator<Student> CREATOR
= new Parcelable.Creator<Student>() {
//从Parcel对象里面读取数据
public Student createFromParcel(Parcel in) {
return new Student(in);
}
public Student[] newArray(int size) {
return new Student[size];
}
};
public Student(Parcel in) {
// TODO Auto-generated constructor stub
no= in.readInt();
name = in.readString();
age = in.readInt();
}
public Student(int no,String name,int age)
{
this.no=no;
this.name=name;
this.age=age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return no+" "+name+" "+age;
}
}
新建一个dial文件来标明它:
Student.dial
package domin;//标明包名
parcelable Student;//标明类名,parcelable要小写
接口:IStudentService.java
package inter;
import domin.Student;
interface IStudentService {
Student queryStudent(int no);
}
建立这个接口后要改为dial文件
然后系统会为此接口改写代码,里面有一个Stub类,这个类继承Binder和IStudentService接口
然后是student服务
StudentService.java
package serve;
import domin.Student;
import inter.IStudentService.Stub;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class StudentService extends Service{
private MyStudentService binder=new MyStudentService();
private Student[] students=new Student[]{new Student(1,"王贺",21),new Student(2,"黎明",22),new Student(3,"线路",23)};
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return binder;
}
private final class MyStudentService extends Stub//由于系统对代码的改写,所以只需要继承Stub类就是对Binder和IStudentService接口的继承
{
@Override
public Student queryStudent(int no) throws RemoteException {
// TODO Auto-generated method stub
return query(no-1);
}
public Student query(int no)
{
return students[no-1];
}
}
}
由于是两个应用所以要对次服务注册下,
Xml配置:
<service android:name="serve.StudentService">
<intent-filter>
<action android:name="com.example.MyServer"/>
</intent-filter>
</service>
客户端代码,要把服务器端的除了StudentService类外,把别的类和包复制到客户端的src里面以保持一致
package com.example.client;
import domin.Student;
import inter.IStudentService;
import inter.IStudentService.Stub;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private EditText txt=null;
private TextView msg=null;
private IStudentService iStudentService;
private MyServiceConnection conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt=(EditText)findViewById(R.id.txt);
msg=(TextView)findViewById(R.id.msg);
conn=new MyServiceConnection();
Intent intent=new Intent();
intent.setAction("com.example.MyServer");
bindService(intent,conn,Context.BIND_AUTO_CREATE);
}
private final class MyServiceConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
// TODO Auto-generated method stub
iStudentService=Stub.asInterface(arg1);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
conn=null;
iStudentService=null;
}
}
public void query(View v)
{
try {
Student student=iStudentService.queryStudent(Integer.valueOf(txt.getText().toString()));
msg.setText(student.toString());
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unbindService(conn);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
HTTP
/**
* @author Dylan
* 本类封装了Android中向web服务器提交数据的两种方式四种方法
*/
public class SubmitDataByHttpClientAndOrdinaryWay {
/**
* 使用get请求以普通方式提交数据
* @param map 传递进来的数据,以map的形式进行了封装
* @param path 要求服务器servlet的地址
* @return 返回的boolean类型的参数
* @throws Exception
*/
public Boolean submitDataByDoGet(Map<String, String> map, String path) throws Exception {
// 拼凑出请求地址
StringBuilder sb = new StringBuilder(path);
sb.append("?");
for (Map.Entry<String, String> entry : map.entrySet()) {
sb.append(entry.getKey()).append("=").append(entry.getValue());
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
String str = sb.toString();
System.out.println(str);
URL Url = new URL(str);
HttpURLConnection HttpConn = (HttpURLConnection) Url.openConnection();
HttpConn.setRequestMethod("GET");
HttpConn.setReadTimeout(5000);
// GET方式的请求不用设置什么DoOutPut()之类的吗?
if (HttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return true;
}
return false;
}
/**
* 普通方式的DoPost请求提交数据
* @param map 传递进来的数据,以map的形式进行了封装
* @param path 要求服务器servlet的地址
* @return 返回的boolean类型的参数
* @throws Exception
*/
public Boolean submitDataByDoPost(Map<String, String> map, String path) throws Exception {
// 注意Post地址中是不带参数的,所以newURL的时候要注意不能加上后面的参数
URL Url = new URL(path);
// Post方式提交的时候参数和URL是分开提交的,参数形式是这样子的:name=y&age=6
StringBuilder sb = new StringBuilder();
// sb.append("?");
for (Map.Entry<String, String> entry : map.entrySet()) {
sb.append(entry.getKey()).append("=").append(entry.getValue());
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
String str = sb.toString();
HttpURLConnection HttpConn = (HttpURLConnection) Url.openConnection();
HttpConn.setRequestMethod("POST");
HttpConn.setReadTimeout(5000);
HttpConn.setDoOutput(true);
HttpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
HttpConn.setRequestProperty("Content-Length", String.valueOf(str.getBytes().length));
OutputStream os = HttpConn.getOutputStream();
os.write(str.getBytes());
if (HttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return true;
}
return false;
}
/**
* 以HttpClient的DoGet方式向服务器发送请数据
* @param map 传递进来的数据,以map的形式进行了封装
* @param path 要求服务器servlet的地址
* @return 返回的boolean类型的参数
* @throws Exception
*/
public Boolean submitDataByHttpClientDoGet(Map<String, String> map, String path) throws Exception {
HttpClient hc = new DefaultHttpClient();
// 请求路径
StringBuilder sb = new StringBuilder(path);
sb.append("?");
for (Map.Entry<String, String> entry : map.entrySet()) {
sb.append(entry.getKey()).append("=").append(entry.getValue());
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
String str = sb.toString();
System.out.println(str);
HttpGet request = new HttpGet(sb.toString());
HttpResponse response = hc.execute(request);
if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
return true;
}
return false;
}
/**
* 以HttpClient的DoPost方式提交数据到服务器
* @param map 传递进来的数据,以map的形式进行了封装
* @param path 要求服务器servlet的地址
* @return 返回的boolean类型的参数
* @throws Exception
*/
public Boolean submintDataByHttpClientDoPost(Map<String, String> map, String path) throws Exception {
// 1. 获得一个相当于浏览器对象HttpClient,使用这个接口的实现类来创建对象,DefaultHttpClient
HttpClient hc = new DefaultHttpClient();
// DoPost方式请求的时候设置请求,关键是路径
HttpPost request = new HttpPost(path);
// 2. 为请求设置请求参数,也即是将要上传到web服务器上的参数
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : map.entrySet()) {
NameValuePair nameValuePairs = new BasicNameValuePair(entry.getKey(), entry.getValue());
parameters.add(nameValuePairs);
}
// 请求实体HttpEntity也是一个接口,我们用它的实现类UrlEncodedFormEntity来创建对象,注意后面一个String类型的参数是用来指定编码的
HttpEntity entity = new UrlEncodedFormEntity(parameters, "UTF-8");
request.setEntity(entity);
// 3. 执行请求
HttpResponse response = hc.execute(request);
// 4. 通过返回码来判断请求成功与否
if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
return true;
}
return false;
}
}