2016-01-21 17:10:59 btt2013 阅读数 1393
  • Android移植基础

    Android视频课程,该课程可以让学员了解Android系统架构、学习如何下载Android源码、编译及开发Android、学习如何追踪Android源码、了解Linux内核启动流程、了解Android启动流程、学习如何移植外部函式库至Android源码中。

    26300 人正在学习 去看看 钟文昌

管理物品种类:

查看物品种类 &添加物品种类

服务端代码:
BussinessServiceImpl.java
// --------------------种类-------------------------
	private KindDao kindDao = new KindDaoImpl();

	/**
	 * 查询全部种类
	 * 
	 * @return 系统中全部种类
	 */
	public List<KindBean> getAllKind() throws AuctionException {
		try {
			List<KindBean> result = new ArrayList<KindBean>();
			List<Kind> kindList = kindDao.findAll();
			for (Kind kind : kindList) {
				result.add(new KindBean(kind.getKind_id(), kind.getKind_name(),
						kind.getKind_desc()));
			}
			return result;
		} catch (Exception e) {
			throw new AuctionException("查询全部种类出现异常,请重试");
		}
	}
	/**
	 * 添加种类
	 * @param kind新增的种类
	 * @return 新增种类的主键
	 */
	public int addKind(Kind kind) throws AuctionException {
		try {
			kindDao.save(kind);
			return kind.getKind_id();
		} catch (Exception e) {
			throw new AuctionException("添加种类出现异常,请重试");
		}
	}
KindDao.java
package com.xbmu.dao;

import java.util.List;
import com.xbmu.bean.Kind;

public interface KindDao {
	/**
	 * 查询所有种类
	 * @return
	 */
	List<Kind> findAll();
	
	/**
	 * 添加种类
	 * @param kind 待添加的种类
	 */
	void save(Kind kind);
}
KindDaoImpl.java
package com.xbmu.dao.impl;

import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.xbmu.bean.Kind;
import com.xbmu.dao.KindDao;
import com.xbmu.util.DBCPUtil;
public class KindDaoImpl implements KindDao {
	QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
	public List<Kind> findAll() {		
		try {
			String sql = "select * from kind";
			List<Kind> kinds = qr.query(sql, new BeanListHandler<Kind>(Kind.class));
			return kinds;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 添加种类:
	 * 遇到问题:需求,想将添加的新数据的id返回,
	 * 使用insert into kind (kind_name,kind_desc) values(?,?);select @@identity as kind_id;语句
	 * 
	 */
	public void save(Kind kind) {
		try {
			String sql = "insert into kind (kind_name,kind_desc) values(?,?)";
			qr.update(sql, kind.getKind_name(),kind.getKind_desc());
			String sql2 = "select @@identity as kind_id";
			//ScalarHandler 的参数为空或null时,返回第一行第一列的数据 
			//ScalarHandler 的参数可以是列的索引(从1开始)或列名 
			Object kind_id = qr.query(sql2, new ScalarHandler(1));
			//因为kind_id在数据库中定义为int型,上面语句返回后为BigInteger型,
			kind.setKind_id(Integer.valueOf(kind_id.toString()));//容易发生类型转换异常
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}
ViewKindServlet.java
package com.xbmu.web.controller;

import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import com.xbmu.business.KindBean;
import com.xbmu.service.BussinessService;
import com.xbmu.service.impl.BussinessServiceImpl;
@WebServlet(urlPatterns="/android/viewKind.jsp")
public class ViewKindServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		BussinessService service = new BussinessServiceImpl();
		List<KindBean> kinds = service.getAllKind();
		String mode = request.getParameter("mode");
		if("android".equals(mode)){
			JSONArray jsonArray = new JSONArray(kinds);
			response.getWriter().println(jsonArray.toString());		
		}else if("web".equals(mode)){
			request.setAttribute("kinds", kinds);
			request.getRequestDispatcher("/manage/viewKind.jsp").forward(request, response);
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
AddKindServlet.java
package com.xbmu.web.controller;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.xbmu.bean.Kind;
import com.xbmu.service.BussinessService;
import com.xbmu.service.impl.BussinessServiceImpl;

@WebServlet(urlPatterns = "/android/addKind.jsp")
public class AddKindServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String mode = request.getParameter("mode");
		// 获取请求参数
		String name = request.getParameter("kindName");
		String desc = request.getParameter("kindDesc");
		// 获取服务类对象
		BussinessService service = new BussinessServiceImpl();
		// 调用业务逻辑层的业务方法添加种类
		int kindId = service.addKind(new Kind(name, desc));
		
		if("android".equals(mode)){
			// 添加成功
			if (kindId > 0) {
				response.getWriter().println("恭喜您,种类添加成功");
			} else {
				response.getWriter().println("对不起,种类添加失败");
			}
		}else if("web".equals(mode)){
			response.getWriter().write("添加种类。2秒后自动转向添加页面");
			response.setHeader("Refresh", "2;URL=" + request.getContextPath()
					+ "/servlet/ViewKindServlet?mode=web");
		}
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
viewKind.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ include file="/manage/header.jsp"%>
<br/>
<table width="80%" align="center" cellpadding="0" cellspacing="1" >
	<tr>
		<td colspan="4" >所有流拍的物品</td> 
	</tr>
	<tr  height="30">
		<th>种类名</th>
		<th>种类描述</th>
	</tr>
	<c:forEach items="${kinds}" var="k" varStatus="vs">
		<tr height="24" class="${vs.index%2==0?'odd':'even' }">
			<td nowrap="nowrap">${k.kindName}</td>
			<td nowrap="nowrap">${k.kindDesc}</td>
		</tr>
	</c:forEach>
</table>
  </body>
</html>
addKind.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ include file="/manage/header.jsp"%>
<br/>
    <form action="${pageContext.request.contextPath}/servlet/AddKindServlet?mode=web" method="post" >
    	<table border="1" width="438" align="center">
    		<tr>
    			<td>种类名称</td>
    			<td>
    				<input type="text" name="kindName"/>
    			</td>
    		</tr>
    		<tr>
    			<td>种类描述</td>
    			<td>
    				<textarea rows="5" cols="45" name="kindDesc"></textarea>
    			</td>
    		</tr>
    		<tr>
    			<td colspan="2">
    				<input type="submit" value="保存"/>
    			</td>
    		</tr>
    	</table>
  </body>
</html>
客户端代码:
查看物品种类:

ManageKind.java

package com.xbmu.auction.activity;

import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import com.xbmu.auction.Callbacks;
import com.xbmu.auction.FragmentActivity;
import com.xbmu.auction.fragment.ManageKindFragment;
public class ManageKind extends FragmentActivity implements Callbacks{

	@Override
	protected Fragment getFragment() {
		return new ManageKindFragment();
	}
	@Override
	public void onItemSelected(Integer id, Bundle bundle) {
		//当用户点击ManageKindFragment中的"添加"按钮时,系统启动AddKindActivity
		Intent intent = new Intent(this, AddKind.class);
		startActivity(intent);
	}
}
ManageKindFragment.java
package com.xbmu.auction.fragment;

import org.json.JSONArray;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListView;
import com.xbmu.auction.Callbacks;
import com.xbmu.auction.R;
import com.xbmu.auction.adapter.KindArrayAdapter;
import com.xbmu.auction.listener.HomeListener;
import com.xbmu.auction.util.DialogUtil;
import com.xbmu.auction.util.HttpUtil;

public class ManageKindFragment extends Fragment {
	//添加种类的id,值随意,只要唯一
	protected static final Integer ADD_KIND = 0x1007;
	private Button bnHome;
	private Button bnAdd;
	private ListView kindList;
	private Callbacks mCallbacks;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.manage_kind, container, false);
		//获取界面布局上的两个按钮
		bnHome = (Button) rootView.findViewById(R.id.bn_home);
		bnAdd = (Button) rootView.findViewById(R.id.bnAdd);
		kindList = (ListView) rootView.findViewById(R.id.kindList);
		
		//设置监听时间
		bnHome.setOnClickListener(new HomeListener(getActivity()));
		bnAdd.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//调用该Fragment所在的Activity的onItemSelected方法
				mCallbacks.onItemSelected(ADD_KIND, null);
			}
		});
		//定义发送请求的url
		String url = HttpUtil.BASE_URL+"viewKind.jsp"+"?mode=android";
		try {
			//向指定URL发送请求,并把响应包装成JSONArray对象
			JSONArray jsonArray = new JSONArray(HttpUtil.getRequest(url));
			//把JSONArray对象包装成Adapter
			kindList.setAdapter(new KindArrayAdapter(jsonArray,getActivity()));
		} catch (Exception e) {
			DialogUtil.showDialog(getActivity(), "服务器响应异常!", false);
			e.printStackTrace();
		}
		return rootView;
	}
	/**当该Fragment被添加、显示到Activity时,回调该方法*/
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		//如果Activity没有实现Callbacks接口,抛出异常
		if(!(activity instanceof Callbacks)){
			throw new IllegalStateException("ManageKindFragment所在的Activity必须实现Callbacks接口");
		}
		//把该Activity当初Callbacks对象
		mCallbacks = (Callbacks) activity;
	}
	/**当该Fragment从它所属的Activity中被删除时回调该方法*/
	@Override
	public void onDetach() {
		super.onDetach();
		mCallbacks = null;
	}
}
KindArrayAdapter.java
package com.xbmu.auction.adapter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.xbmu.auction.R;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class KindArrayAdapter extends BaseAdapter {
	// 需要包装的JSONArray
	private JSONArray kindArray;
	private Context context;

	public KindArrayAdapter(JSONArray kindArray, Context context) {
		this.kindArray = kindArray;
		this.context = context;
	}

	@Override
	public int getCount() {
		// 返回ListView包含的列表项的数量
		return kindArray.length();
	}

	@Override
	public Object getItem(int position) {
		// 获取指定列表项所包装的JSONObject
		return kindArray.optJSONObject(position);
	}

	@Override
	public long getItemId(int position) {
		try {
			return ((JSONObject) getItem(position)).getInt("id");
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return -1;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		//定义一个线性布局管理器
		LinearLayout container = new LinearLayout(context);
		//设置为垂直的线性布局管理器
		container.setOrientation(LinearLayout.VERTICAL);
		//定义一个线性布局管理器
		LinearLayout linear = new LinearLayout(context);
		//设置为水平的线性布局管理器
		linear.setOrientation(LinearLayout.HORIZONTAL);
		
		//创建一个ImageView
		ImageView iv = new ImageView(context);
		iv.setPadding(10, 0, 20, 0);
		iv.setImageResource(R.drawable.item);
		//将图片添加到LinearLayout中
		linear.addView(iv);
		//创建一个TextView
		TextView tv = new TextView(context);
		
		try {
			//获取JSONArray数组元素的kindName属性
			String kindName = ((JSONObject)getItem(position)).getString("kindName");
			//设置TextView所显示的内容
			tv.setText(kindName);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		tv.setTextSize(20);
		//将TextView添加到LinearLayout中
		linear.addView(tv);
		container.addView(linear);
		//定义一个文本框来显示种类描述
		TextView descView = new TextView(context);
		descView.setPadding(30, 0, 0, 0);
		
		//获取JSONArray数组元素的kindDesc属性
		try {
			String kindDesc = ((JSONObject)getItem(position)).getString("kindDesc");
			descView.setText(kindDesc);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		descView.setTextSize(16);
		container.addView(descView);
		return container;
	}

}
manage_kind.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/sub_title_margin"
        android:gravity="center"
        android:orientation="horizontal" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/manage_kind"
                android:textSize="@dimen/label_font_size" />
            <!-- 添加种类的按钮 -->

            <Button
                android:id="@+id/bnAdd"
                android:layout_width="85dp"
                android:layout_height="30dp"
                android:background="@drawable/add_kind" />
        </LinearLayout>

        <Button
            android:id="@+id/bn_home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/label_font_size"
            android:background="@drawable/home" />
    </LinearLayout>
    <!-- 显示种类列表的ListView -->

    <ListView
        android:id="@+id/kindList"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

添加物品种类:
AddKind.java
package com.xbmu.auction.activity;

import android.app.Fragment;

import com.xbmu.auction.FragmentActivity;
import com.xbmu.auction.fragment.AddKindFragment;

public class AddKind extends FragmentActivity {

	@Override
	protected Fragment getFragment() {
		return new AddKindFragment();
	}
}
AddKindFragment.java
package com.xbmu.auction.fragment;

import java.util.HashMap;
import java.util.Map;
import android.app.Fragment;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import com.xbmu.auction.R;
import com.xbmu.auction.listener.HomeListener;
import com.xbmu.auction.util.DialogUtil;
import com.xbmu.auction.util.HttpUtil;

public class AddKindFragment extends Fragment {
	private EditText kindName;
	private EditText kindDesc;
	private Button bnAdd;
	private Button bnCancel;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.add_kind, container, false);
		kindName = (EditText) rootView.findViewById(R.id.kindName);
		kindDesc = (EditText) rootView.findViewById(R.id.kindDesc);
		bnAdd = (Button) rootView.findViewById(R.id.bnAdd);
		bnCancel = (Button) rootView.findViewById(R.id.bnCancel);

		bnCancel.setOnClickListener(new HomeListener(getActivity()));
		bnAdd.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// 输入校验
				if (validate()) {
					// 获取用户输入的种类名称和描述
					String name = kindName.getText().toString().trim();
					String desc = kindDesc.getText().toString().trim();
					try {
						// 添加物品种类
						String result = addKind(name, desc);
						// 使用对话框来显示添加结果
						DialogUtil.showDialog(getActivity(), result, true);
					} catch (Exception e) {
						DialogUtil.showDialog(getActivity(), "服务器响应异常,请稍后重试!",
								false);
						e.printStackTrace();
					}
				}
			}
		});
		return rootView;
	}

	/**
	 * 添加种类
	 * @throws Exception
	 */
	protected String addKind(String name, String desc) throws Exception {
		// 使用Map封装请求参数
		Map<String, String> map = new HashMap<String, String>();
		map.put("kindName", name);
		map.put("kindDesc", desc);
		// 定义发送请求的url
		String url = HttpUtil.BASE_URL + "addKind.jsp"+"?mode=android";;
		// 发送请求
		return HttpUtil.postRequest(url, map);
	}

	/** 对用户输入的种类名称进行数据校验 */
	protected boolean validate() {
		String name = kindName.getText().toString().trim();
		if (TextUtils.isEmpty(name)) {
			DialogUtil.showDialog(getActivity(), "种类名称必须填", false);
			return false;
		}
		return true;
	}
}
add_kind.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:stretchColumns="1" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="@dimen/title_padding"
        android:text="@string/add_kind_title"
        android:textSize="@dimen/label_font_size" />

    <TableRow>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/kind_name"
            android:textSize="@dimen/label_font_size" />

        <EditText
            android:id="@+id/kindName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="text" />
    </TableRow>

    <TableRow>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/kind_desc"
            android:textSize="@dimen/label_font_size" />

        <EditText
            android:id="@+id/kindDesc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="text" />
    </TableRow>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center" >

        <Button
            android:id="@+id/bnAdd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/add" />

        <Button
            android:id="@+id/bnCancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/cancel" />
    </LinearLayout>

</TableLayout>
运行效果:


查询数据库中是否有刚添加的数据:

这里严重存在一个问题,待解决:
数据库主键自增ID 删除后 出现断号 怎么让其重新顺号?


2016-01-18 14:24:38 btt2013 阅读数 3217
  • Android移植基础

    Android视频课程,该课程可以让学员了解Android系统架构、学习如何下载Android源码、编译及开发Android、学习如何追踪Android源码、了解Linux内核启动流程、了解Android启动流程、学习如何移植外部函式库至Android源码中。

    26300 人正在学习 去看看 钟文昌

一、搭建简单的web服务器

首先简单看一下web工程目录及其包的构建:

导入jar包

业务层接口:BussinessService.java
package com.xbmu.service;

import java.util.List;
import com.xbmu.bean.Bid;
import com.xbmu.bean.Item;
import com.xbmu.bean.Kind;
import com.xbmu.business.BidBean;
import com.xbmu.business.ItemBean;
import com.xbmu.business.KindBean;
import com.xbmu.exception.AuctionException;
/**
 * 业务层接口(主要声明一些主要的功能)
 * @author Administrator
 *
 */
public interface BussinessService{
	/**
	 * 根据赢取者查询物品
	 * @param winerId 赢取者的ID
	 * @return 赢取者获得的全部物品
	 */
	List<ItemBean> getItemByWiner(Integer winerId)
		throws AuctionException;

	/**
	 * 查询流拍的全部物品
	 * @return 全部流拍物品
	 */
	List<ItemBean> getFailItems()throws AuctionException;

	/**
	 * 根据用户名,密码验证登录是否成功
	 * @param username 登录的用户名
 	 * @param pass 登录的密码
	 * @return 登录成功返回用户ID,否则返回-1
	 */
	int validLogin(String username , String pass)
		throws AuctionException;

	/**
	 * 查询用户的全部出价
	 * @param userId 竞价用户的ID
	 * @return 用户的全部出价
	 */
	List<BidBean> getBidByUser(Integer userId)
		throws AuctionException;

	/**
	 * 根据用户查找目前仍在拍卖中的全部物品
	 * @param userId 所属者的ID
	 * @return 属于当前用户的、处于拍卖中的全部物品。
	 */
	List<ItemBean> getItemsByOwner(Integer userId)
		throws AuctionException;

	/**
	 * 查询全部种类
	 * @return 系统中全部全部种类
	 */
	List<KindBean> getAllKind() throws AuctionException;

	/**
	 * 添加物品
	 * @param item 新增的物品
	 * @param avail 有效天数
	 * @param kindId 物品种类ID
	 * @param userId 添加者的ID
	 * @return 新增物品的主键
	 */
	int addItem(Item item, int avail , int kindId , Integer userId)
		throws AuctionException;

	/**
	 * 添加种类
	 * @param kind 新增的种类
	 * @return 新增种类的主键
	 */
	int addKind(Kind kind) throws AuctionException;

	/**
	 * 根据产品分类,获取处于拍卖中的全部物品
	 * @param kindId 种类id;
	 * @return 该类的全部产品
	 */
	List<ItemBean> getItemsByKind(int kindId) throws AuctionException;

	/**
	 * 根据种类id获取种类名
	 * @param kindId 种类id;
	 * @return 该种类的名称
	 */
	String getKind(int kindId) throws AuctionException;

	/**
	 * 根据物品id,获取物品
	 * @param itemId 物品id;
	 * @return 指定id对应的物品
	 */
	ItemBean getItem(int itemId) throws AuctionException;

	/**
	 * 增加新的竞价,并对竞价用户发邮件通知
	 * @param itemId 物品id;
	 * @param bid 竞价
	 * @param userId 竞价用户的ID
	 * @return 返回新增竞价记录的ID
	 */
	int addBid(int itemId , Bid bid ,Integer userId)
		throws AuctionException;

	/**
	 * 根据时间来修改物品的赢取者
	 */
	void updateWiner()throws AuctionException;
}
完成登录功能模块:
BussinessServiceImpl.java
package com.xbmu.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.xbmu.bean.Bid;
import com.xbmu.bean.Item;
import com.xbmu.bean.Kind;
import com.xbmu.bean.User;
import com.xbmu.business.BidBean;
import com.xbmu.business.ItemBean;
import com.xbmu.business.KindBean;
import com.xbmu.dao.AuctionUserDao;
import com.xbmu.dao.ItemDao;
import com.xbmu.dao.impl.AuctionUserDaoImpl;
import com.xbmu.dao.impl.ItemDaoImpl;
import com.xbmu.exception.AuctionException;
import com.xbmu.service.BussinessService;

public class BussinessServiceImpl implements BussinessService {
	//---------------------用户----------------------------
	private AuctionUserDao userDao = new AuctionUserDaoImpl();
	/**
	 * 根据用户名,密码验证登录是否成功
	 * @param username 登录的用户名
	 * @param pass 登录的密码
	 * @return 登录成功返回用户ID,否则返回-1
	 */
	public int validLogin(String username, String pass) throws AuctionException {
		User user = userDao.findUserByNameAndPass(username, pass);
		if(user!=null){
			return user.getUser_id();
		}
		return -1;
	}
	//...
}
AuctionUserDao.java
package com.xbmu.dao;

import com.xbmu.bean.User;

/**
 * 数据访问层,用户接口
 * @author Administrator
 *
 */
public interface AuctionUserDao {
	/**
	 * 验证用户登录
	 * @param username 用户名
	 * @param pass 用户密码
	 * @return 验证成功,返回一个用户;否则返回null
	 */
	User findUserByNameAndPass(String username, String pass);
}
AuctionUserDaoImpl.java
package com.xbmu.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.xbmu.bean.User;
import com.xbmu.dao.AuctionUserDao;
import com.xbmu.util.DBCPUtil;

public class AuctionUserDaoImpl implements AuctionUserDao {
	private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
	public User findUserByNameAndPass(String username, String pass) {
		String sql = "select * from auction_user where username=? and userpass=?";
		try {
			List<User> userList = qr.query(sql, new BeanListHandler<User>(User.class), username,pass);
			if (userList.size() == 1)
			{
				return (User)userList.get(0);
			}
			return null;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

}
LoginServlet.java
package com.xbmu.web.controller;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONException;
import org.json.JSONObject;
import com.xbmu.service.BussinessService;
import com.xbmu.service.impl.BussinessServiceImpl;

/**
 * Servlet3.0以后出现了注解。因此Servlet配置方式就有了两种: 
 * 1、在web.xml文件中配置。
 * 2、通过注解配置。
 * 		比如:@WebServlet(urlPatterns="/android/login.jsp")配置后,客户端就可以通过访问此路径访问该servlet
 */
@WebServlet(urlPatterns = "/android/login.jsp")
public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取模式请求参数。android:表示客户端请求地址,web:表示后台请求地址
		String mode = request.getParameter("mode");
		if("android".equals(mode)){
			Integer userId = validateLogin(request);
			try {
				JSONObject jsonObject = new JSONObject();
				//把验证的userId封装成JSONObject
				jsonObject.put("userId", userId);
				//输出响应
				response.getWriter().println(jsonObject.toString());
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}else if("web".equals(mode)){
			Integer userId = validateLogin(request);
			//转发到首页
			request.getRequestDispatcher("/manage/index.jsp").forward(request, response);
		}
		
	}
	/**
	 * 验证用户登录
	 * @param request
	 * @return 登录成功,返回用户id
	 */
	private Integer validateLogin(HttpServletRequest request) {
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		//获取业务逻辑对象
		BussinessService service = new BussinessServiceImpl();
		//验证用户登录
		Integer userId = service.validLogin(username, password);
		if (userId > 0) {
			//将用户ID放入HTTP session中,方便以后程序跟踪用户的登录状态
			request.getSession(true).setAttribute("userId", userId);
		}
		return userId;
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页面</title>
</head>
<body>
	<div align="center">
		<h2>欢迎您,使用电子拍卖系统</h2>
		<form action="${pageContext.request.contextPath}/servlet/LoginServlet?mode=web" method="post">
			用户账号:<input type="text" name="username" /><br/> 
			用户密码:<input type="password" name="password" /><br/> 
			<input type="submit" value="登录" />
		</form>
	</div>
</body>
</html>
请求地址:
服务端:
	登录界面:http://localhost:8080/AuctionServer/manage/login.jsp  
	登录表单action="http://localhost:8080/AuctionServer/servlet/LoginServlet?mode=web"
客户端:
	登录访问地址:
		http://localhost:8080/AuctionServer/android/login.jsp?mode=android
		(http://localhost:8080/AuctionServer/servlet/LoginServlet?mode=android)

二、客户端开发:

搭建开发环境,创建项目:

一、登录模块:

登录流程图:

FutureTask类介绍:

FutureTask是一种可以取消的异步的计算任务。它的计算是通过Callable实现的,它等价于可以携带结果的Runnable,并且有三个状态:等待、运行和完成。
完成包括所有计算以任意的方式结束,包括正常结束、取消和异常。
Future有个get方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常。
FutureTask有下面几个重要的方法:
1.get()
阻塞一直等待执行完成拿到结果
2.get(int timeout, TimeUnit timeUnit)
阻塞一直等待执行完成拿到结果,如果在超时时间内,没有拿到抛出异常
3.isCancelled()
是否被取消
4.isDone()
是否已经完成
5.cancel(boolean mayInterruptIfRunning)
试图取消正在执行的任务

访问网络的工具类HttpUtil.java
package com.xbmu.auction.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
 * 访问网络的工具类,采用了Apache 下的HttpClient类
 * @author Administrator
 *
 */
public class HttpUtil
{
	// 创建HttpClient对象
	public static HttpClient httpClient = new DefaultHttpClient();
	public static final String BASE_URL =
		"http://10.0.2.2:8080/AuctionServer/android/";
	/**
	 *
	 * @param url 发送请求的URL
	 * @return 服务器响应字符串
	 * @throws Exception
	 */
	public static String getRequest(final String url)
		throws Exception
	{
		FutureTask<String> task = new FutureTask<String>(
		new Callable<String>()
		{
			@Override
			public String call() throws Exception
			{
				// 创建HttpGet对象。
				HttpGet get = new HttpGet(url);
				// 发送GET请求
				HttpResponse httpResponse = httpClient.execute(get);
				// 如果服务器成功地返回响应
				if (httpResponse.getStatusLine()
					.getStatusCode() == 200)
				{
					// 获取服务器响应字符串
					String result = EntityUtils
						.toString(httpResponse.getEntity());
					return result;
				}
				return null;
			}
		});
		new Thread(task).start();
		return task.get();
	}

	/**
	 * @param url 发送请求的URL
	 * @param params 请求参数
	 * @return 服务器响应字符串
	 * @throws Exception
	 */
	public static String postRequest(final String url
		, final Map<String ,String> rawParams)throws Exception
	{
		FutureTask<String> task = new FutureTask<String>(
		new Callable<String>()
		{
			@Override
			public String call() throws Exception
			{
				// 创建HttpPost对象。
				HttpPost post = new HttpPost(url);
				// 如果传递参数个数比较多的话可以对传递的参数进行封装
				List<NameValuePair> params = 
					new ArrayList<NameValuePair>();
				for(String key : rawParams.keySet())
				{
					//封装请求参数
					params.add(new BasicNameValuePair(key 
						, rawParams.get(key)));
				}
				// 设置请求参数
				post.setEntity(new UrlEncodedFormEntity(
					params, "utf-8"));
				// 发送POST请求
				HttpResponse httpResponse = httpClient.execute(post);
				// 如果服务器成功地返回响应
				if (httpResponse.getStatusLine()
					.getStatusCode() == 200)
				{
					// 获取服务器响应字符串
					String result = EntityUtils
						.toString(httpResponse.getEntity());
					return result;
				}
				return null;
			}
		});
		new Thread(task).start();
		return task.get();
	}
}
LoginActivity.java
package com.xbmu.auction;

import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import com.xbmu.auction.util.DialogUtil;
import com.xbmu.auction.util.HttpUtil;
/**
 * 登录界面的Activity
 * @author Administrator
 *
 */
public class LoginActivity extends Activity {

	private EditText etUser;
	private EditText etPwd;
	private Button btnLogin;
	private Button btnCancel;
	private String username;
	private String password;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_login);
		etUser = (EditText) findViewById(R.id.et_user);
		etPwd = (EditText) findViewById(R.id.et_pwd);
		
		btnLogin = (Button) findViewById(R.id.btn_Login);
		btnCancel = (Button) findViewById(R.id.btn_Cancel);

		btnLogin.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//1.校验用户信息
				if(validate()){
					//2.如果信息正确,登录应用
					if(loginPro()){
						//3.登录成功,启动主Activity
						Intent intent = new Intent(LoginActivity.this, AuctionClientActivity.class);
						startActivity(intent);
						//结束该Activity
						finish();
					}else{
						DialogUtil.showDialog(LoginActivity.this, "用户名或者密码错误,请重新输入!", false);
					}
				}
			}
		});
	}
	/**用于登录信息验证成功后,登录程序*/
	protected boolean loginPro() {
		try {
			JSONObject jsonObject = query(username,password);
			//如果userId > 0
			if(jsonObject.getInt("userId") > 0){
				return true;
			}
		} catch (Exception e) {
			DialogUtil.showDialog(this, "服务器响应异常,请稍后再试!", false);
			e.printStackTrace();
		}
		return false;
	}
	/**
	 * 发送请求的方法
	 * @param username
	 * @param password
	 * @return
	 * @throws Exception 
	 */
	private JSONObject query(String username, String password) throws Exception {
		//使用Map封装请求参数
		Map<String, String> map = new HashMap<String, String>();
		map.put("username", username);
		map.put("password", password);
		//发送请求的URL
		String url = HttpUtil.BASE_URL+"login.jsp"+"?mode=android";
		System.out.println(HttpUtil.postRequest(url, map));
		//发送请求
		return new JSONObject(HttpUtil.postRequest(url, map));
	}
	/**对用户输入的用户名、密码进行校验*/
	protected boolean validate() {
		username = etUser.getText().toString().trim();
		password = etPwd.getText().toString().trim();
		if(TextUtils.isEmpty(username)){
			DialogUtil.showDialog(this, "用户账号是必填项", false);
			return false;
		}
		if(TextUtils.isEmpty(password)){
			DialogUtil.showDialog(this, "用户密码是必填项", false);
			return false;
		}
		return true;
	}
}
登录界面使用了表格布局,我们这里简单介绍下表格布局的常用属性:
android:shrinkColumns:设置允许被收缩的列的列序号。多个序列号之间用逗号隔开。
android:stretchColumns:设置允许被拉伸的列的列序号。多个序列号之间用逗号隔开。
android:collapseColumns:设置需要被隐藏的列的列序号。多个序列号之间用逗号隔开。

activity_login.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="300dp"
    android:layout_height="match_parent"
    android:layout_gravity="center_horizontal"
    android:stretchColumns="1">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/hello"
        android:scaleType="fitCenter"
        android:src="@drawable/logo" />

    <TextView
        android:id="@+id/TextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="@dimen/title_padding"
        android:text="@string/welcome"
        android:textSize="@dimen/label_font_size" />
    <!-- 输入用户名的行 -->

    <TableRow>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/user_name"
            android:textSize="@dimen/label_font_size" />

        <EditText
            android:id="@+id/et_user"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="text" />
    </TableRow>
    <!-- 输入密码的行 -->

    <TableRow>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/user_pass"
            android:textSize="@dimen/label_font_size" />

        <EditText
            android:id="@+id/et_pwd"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword"
            android:text="" />
    </TableRow>
    <!-- 定义登录、取消按钮的行 -->

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/btn_Login"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/login" />

        <Button
            android:id="@+id/btn_Cancel"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/cancel" />
    </LinearLayout>

</TableLayout>
DialogUtil.java
package com.xbmu.auction.util;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.view.View;

import com.xbmu.auction.AuctionClientActivity;
/**
 * 项目要用到许多对话框,这里封装一个对话框的工具类。便于显示对话框
 * @author Administrator
 *
 */
public class DialogUtil {
	/**
	 * 定义一个显示消息的对话框
	 * 
	 * @param context 上下文
	 * @param msg 对话框显示的描述信息
	 * @param goHome 标记,为true表示登录成功,为false登录失败
	 */
	public static void showDialog(final Context context, String msg,
			boolean goHome) {
		//创建一个AlertDialog.Builder对象
		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setMessage(msg);
		builder.setCancelable(false);
		if (goHome) {
			//登录成功,跳转到AuctionClientActivity(也就是应用程序的主界面)界面
			builder.setPositiveButton("确定", new OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					Intent intent = new Intent(context,
							AuctionClientActivity.class);
					intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
					context.startActivity(intent);
				}
			});
		} else {
			builder.setPositiveButton("确定", null);
		}
		builder.create().show();
	}
	/**
	 * 定义一个显示指定组件(布局)的对话框
	 * @param context
	 * @param view
	 */
	public static void showDialog(Context context, View view) {
		new AlertDialog.Builder(context).setView(view).setCancelable(false)
				.setPositiveButton("确定", null).create().show();
	}
}
AuctionClientActivity.java
package com.xbmu.auction;

import android.app.Activity;
import android.os.Bundle;
/**
 * 应用程序主界面
 * @author Administrator
 *
 */
public class AuctionClientActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
}
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="action_settings">Settings</string>
    <string name="app_name">电子拍卖</string>
    <string name="welcome">欢迎使用电子拍卖系统</string>
    <string name="hello_world">Hello world!</string>
    <string name="user_name">用户账号:</string>
    <string name="user_pass">用户密码</string>
    <string name="login">登录</string>
    <string name="cancel">取消</string>
    <string name="hello">Hello World, Login!</string>

</resources>
res/values/dimens.xml
<resources>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="title_padding">10dp</dimen>
    <dimen name="label_font_size">20dp</dimen>

</resources>
记得在清单文件中加入访问网络的权限:
<uses-permission android:name="android.permission.INTERNET"/>
运行效果:(记得先开启服务器)

二、进入主页面

auction_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="@dimen/title_padding"
        android:text="@string/welcome"
        android:textSize="@dimen/label_font_size" />

    <ListView
        android:id="@+id/auction_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:entries="@array/auction_list" />

</LinearLayout>
AuctionListFragment.java
package com.xbmu.auction.view;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.xbmu.auction.Callbacks;
import com.xbmu.auction.R;

/**
 * 自定义的Fragment,该Fragment种显示一个ListView,每个ListView条目代表一个系统功能
 * 
 * @author Administrator
 * 
 */
public class AuctionListFragment extends Fragment {
	ListView auctionList;
	private Callbacks mCallbacks;	
	/**重写该方法,该方法返回的View将作为Fragment显示的组件*/
	@Override
	public View onCreateView(LayoutInflater inflater
		, ViewGroup container, Bundle savedInstanceState)
	{
		View rootView = inflater.inflate(R.layout.auction_list,
			container, false);
		auctionList = (ListView) rootView.findViewById(
			R.id.auction_list);
		// 为ListView的列表项的单击事件绑定事件监听器
		auctionList.setOnItemClickListener(new OnItemClickListener()
		{

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
				int position, long id)
			{
				mCallbacks.onItemSelected(position , null);
			}
		});
		return rootView;
	}	
	
	/**当该Fragment被添加、显示到Activity时,回调该方法*/
	@Override
	public void onAttach(Activity activity)
	{
		super.onAttach(activity);
		// 如果Activity没有实现Callbacks接口,抛出异常
		if (!(activity instanceof Callbacks))
		{
			throw new IllegalStateException(
				"AuctionListFragment所在的Activity必须实现Callbacks接口!");
		}
		// 把该Activity当成Callbacks对象
		mCallbacks = (Callbacks) activity;
	}
	/**当该Fragment从它所属的Activity中被删除时回调该方法*/
	@Override
	public void onDetach()
	{
		super.onDetach();
		// 将mCallbacks赋为null。
		mCallbacks = null;
	}
	/**
	 * 设置:激活条目点击
	 * @param activateOnItemClick
	 */
	public void setActivateOnItemClick(boolean activateOnItemClick)
	{	//设置ListView的选择行为。该属性支持如下属性值
		/*
		 * none:不显示任何选中项
		 * singleChoice:允许单选
		 */
		auctionList.setChoiceMode(activateOnItemClick 
			? ListView.CHOICE_MODE_SINGLE
			: ListView.CHOICE_MODE_NONE);
	}
}
Callbacks.java
package com.xbmu.auction;

import android.os.Bundle;

/**
 * 定义一个回调接口,里面定义一些回调方法。用于优化代码
 * @author Administrator
 *
 */
public interface Callbacks {
	/**
	 * 单个条目被选中,调用该方法。
	 * @param id
	 * @param bundle
	 */
	public void onItemSelected(Integer id,Bundle bundle);
}
将Fragment添加到Activity中有如下两种方法:
1、在布局文件中使用<fragment />元素添加到Fragment,<fragment />元素的android:name属性指定Fragment的实现类。
2、在java代码中通过FragmentTransaction对象的add()方法来添加Fragment
activity_main.xml
<LinearLayout 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:orientation="horizontal" >
	<!--添加一个自定义的Fragment  -->
	<fragment
		android:name="com.xbmu.auction.view.AuctionListFragment"
		android:id="@+id/auction_list"
		android:layout_width="match_parent"
		android:layout_height="match_parent"/>
</LinearLayout>
Activity获取它包含的Fragment:调用Activity关联的FragmentManager的findFragmentById(int id)或findFragmentByTag(String tag)方法即可获取指定的Fragment
AuctionClientActivity.java
package com.xbmu.auction;

import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import com.xbmu.auction.activity.ChooseKind;
import com.xbmu.auction.activity.ManageItem;
import com.xbmu.auction.activity.ManageKind;
import com.xbmu.auction.activity.ViewBid;
import com.xbmu.auction.activity.ViewItem;
import com.xbmu.auction.view.AuctionListFragment;
/**
 * 应用程序主界面
 * @author Administrator
 *
 */
public class AuctionClientActivity extends Activity implements Callbacks{
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		FragmentManager fm = getFragmentManager();
		AuctionListFragment auctionList = (AuctionListFragment) fm.findFragmentById(R.id.auction_list);
		auctionList.setActivateOnItemClick(true);
	}

	@Override
	public void onItemSelected(Integer id, Bundle bundle) {
		Intent intent = null;
		switch ((int)id) {
		// 查看竞得物品
		case 0:
			// 启动ViewItem Activity
			intent = new Intent(this, ViewItem.class);
			// action属性为请求的Servlet地址。
			intent.putExtra("action", "viewSucc.jsp");
			startActivity(intent);
			break;
		// 浏览流拍物品
		case 1:
			// 启动ViewItem Activity
			intent = new Intent(this, ViewItem.class);
			// action属性为请求的Servlet的URL。
			intent.putExtra("action", "viewFail.jsp");
			startActivity(intent);
			break;
		// 管理物品种类
		case 2:
			// 启动ManageKind Activity
			intent = new Intent(this, ManageKind.class);
			startActivity(intent);
			break;
		// 管理物品
		case 3:
			// 启动ManageItem Activity
			intent = new Intent(this, ManageItem.class);
			startActivity(intent);
			break;
		// 浏览拍卖物品(选择物品种类)
		case 4:
			// 启动ChooseKind Activity
			intent = new Intent(this, ChooseKind.class);
			startActivity(intent);
			break;
		// 查看自己的竞标
		case 5:
			// 启动ViewBid Activity
			intent = new Intent(this, ViewBid.class);
			startActivity(intent);
			break;
		}
	}
}
提示:
在界面布局文件中使用<fragment />元素添加Fragment时,可以为<fragment />元素指定android:id或android:tag属性,这两个属性都可用于标识该Fragment,接下来Activity将可通过findFragmentById(int id)或findFragmentByTag(String tag)来获取该Fragment。
FragmentActivity.java
package com.xbmu.auction;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.widget.LinearLayout;

public abstract class FragmentActivity extends Activity{
	private static final int ROOT_CONTAINER_ID = 0x90001;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		LinearLayout layout = new LinearLayout(this);
		setContentView(layout);
		layout.setId(ROOT_CONTAINER_ID);
		getFragmentManager().beginTransaction()
			.replace(ROOT_CONTAINER_ID , getFragment())
			.commit();
	}
	protected abstract Fragment getFragment();
}
ViewItem.java
package com.xbmu.auction.activity;

import android.app.Fragment;

import com.xbmu.auction.FragmentActivity;

/**
 * 浏览流拍物品
 * @author Administrator
 */
public class ViewItem extends FragmentActivity {

	@Override
	protected Fragment getFragment() {
		// TODO Auto-generated method stub
		return null;
	}
}
其中ChooseKind.java、ManageItem.java、ManageKind.java、ViewBid.java这几个文件暂时性和ViewItem的内容差不多。
res/values/array.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="auction_list">
        <item>查看竞得物品</item>
        <item>浏览流拍物品</item>
        <item>管理物品种类</item>
        <item>管理物品</item>
        <item>浏览拍卖物品</item>
        <item>查看自己的竞标</item>
    </string-array>
</resources>
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="action_settings">Settings</string>
    <string name="app_name">电子拍卖</string>
    <string name="welcome">欢迎使用电子拍卖系统</string>
    <string name="hello_world">Hello world!</string>
    <string name="user_name">用户账号:</string>
    <string name="user_pass">用户密码</string>
    <string name="login">登录</string>
    <string name="cancel">取消</string>
    <string name="hello">Hello World, Login!</string>
    <string name="manage_kind">系统的所有物品种类</string>
    <string name="manage_item">你当前的拍卖物品</string>
    <string name="view_bid">你参与竞标的物品</string>
    <string name="choose_kind">请选择一个物品的种类</string>

</resources>
在清单文件中注册:
<activity
            android:name=".AuctionClientActivity"
            android:label="@string/app_name" >
        </activity>
        <activity
            android:name="com.xbmu.auction.activity.ViewItem"
            android:label="@string/app_name" >
        </activity>
        <activity
            android:name="com.xbmu.auction.activity.ManageKind"
            android:label="@string/manage_kind" >
        </activity>
        <activity
            android:name="com.xbmu.auction.activity.ManageItem"
            android:label="@string/manage_item" >
        </activity>
        <activity
            android:name="com.xbmu.auction.activity.ViewBid"
            android:label="@string/view_bid" >
        </activity>
        <activity
            android:name="com.xbmu.auction.activity.ChooseKind"
            android:label="@string/choose_kind" >
        </activity>
运行效果:

三、实现主页面各个功能:

3.1:浏览流拍物品:

在服务器上写浏览流拍物品功能:
BussinessServiceImpl.java
package com.xbmu.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.xbmu.bean.Bid;
import com.xbmu.bean.Item;
import com.xbmu.bean.Kind;
import com.xbmu.bean.User;
import com.xbmu.business.BidBean;
import com.xbmu.business.ItemBean;
import com.xbmu.business.KindBean;
import com.xbmu.dao.AuctionUserDao;
import com.xbmu.dao.ItemDao;
import com.xbmu.dao.KindDao;
import com.xbmu.dao.impl.AuctionUserDaoImpl;
import com.xbmu.dao.impl.ItemDaoImpl;
import com.xbmu.dao.impl.KindDaoImpl;
import com.xbmu.exception.AuctionException;
import com.xbmu.service.BussinessService;

public class BussinessServiceImpl implements BussinessService {
	//...
	// ---------------------物品----------------------------
	private ItemDao itemDao = new ItemDaoImpl();

	/**
	 * 查询流拍的全部物品
	 * 
	 * @return 全部流拍物品
	 */
	public List<ItemBean> getFailItems() throws AuctionException {
		try {
			List<Item> items = itemDao.findItemByState(3);
			List<ItemBean> result = new ArrayList<ItemBean>();
			for (Iterator<Item> it = items.iterator(); it.hasNext();) {
				ItemBean ib = new ItemBean();
				initItem(ib, it.next());
				result.add(ib);
			}
			return result;
		} catch (Exception e) {
			throw new AuctionException("查询流拍物品出现异常,请重试");
		}
	}
	//....
	/**
	 * 将一个Item PO转换成ItemBean的VO
	 * @param ib  ItemBean的VO
	 * @param item Item的PO
	 */
	private void initItem(ItemBean ib, Item item) {
		ib.setId(item.getItem_id());
		ib.setName(item.getItem_name());
		ib.setDesc(item.getItem_desc());
		ib.setRemark(item.getItem_remark());
		if (item.getKind() != null)
			ib.setKind(item.getKind().getKind_name());
		if (item.getOwner() != null)
			ib.setOwner(item.getOwner().getUsername());
		if (item.getWiner() != null)
			ib.setWiner(item.getWiner().getUsername());
		ib.setAddTime(item.getAddtime());
		ib.setEndTime(item.getEndtime());
		if (item.getItemState() != null)
			ib.setState(item.getItemState().getState_name());
		ib.setInitPrice(item.getInit_price());
		ib.setMaxPrice(item.getMax_price());
	}

}
ItemDao.java
package com.xbmu.dao;

import java.util.List;
import com.xbmu.bean.Item;
/**
 * 物品接口
 * @author Administrator
 *
 */
public interface ItemDao{
	/**
	 * 根据物品状态查找物品
	 * @param stateId 状态Id;
	 * @return 该状态下的全部物品
	 */
	List<Item> findItemByState(Integer stateId);
}
ItemDaoImpl.java
package com.xbmu.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.xbmu.bean.Item;
import com.xbmu.bean.Kind;
import com.xbmu.bean.User;
import com.xbmu.dao.ItemDao;
import com.xbmu.util.DBCPUtil;

public class ItemDaoImpl implements ItemDao {
	QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
	/**
	 * 根据物品状态查找物品
	 * @param stateId 状态id;
	 * @return 该状态下的全部物品
	 */
	public List<Item> findItemByState(Integer stateId) {
		try {
			String sql = "select * from item where state_id = ?";
			List<Item> itemList  = qr.query(sql, new BeanListHandler<Item>(Item.class),stateId);
			
			//遍历物品,设置种类,赢取者,拥有者的属性。
			for (Item item : itemList) {
				//设置种类
				String kindSql = "select * from kind where kind_id = (select kind_id from item where state_id=?)";
				Kind kind = qr.query(kindSql, new BeanHandler<Kind>(Kind.class), stateId);
				item.setKind(kind);
				
				//设置拥有者用户
				String ownerSql = "select * from auction_user where user_id = (select owner_id from item where state_id=?)";
				User owner = qr.query(ownerSql, new BeanHandler<User>(User.class), stateId);
				item.setOwner(owner);
				
				//设置赢取者用户
				String winerSql = "select * from auction_user where user_id = (select winer_id from item where state_id=?)";
				User winer = qr.query(winerSql, new BeanHandler<User>(User.class), stateId);
				item.setWiner(winer);
				System.out.println(item.toString());
			}
			return itemList;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	//...
}
ViewFailServlet.java
package com.xbmu.web.controller;

import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import com.xbmu.business.ItemBean;
import com.xbmu.service.BussinessService;
import com.xbmu.service.impl.BussinessServiceImpl;

/**
 * 查看流拍物品的Servlet
 * 
 * @author Administrator
 * 
 */
@WebServlet(urlPatterns = "/android/viewFail.jsp")
public class ViewFailServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取请求参数,这个参数标记的是返回的json数据,用于提供给客户端
		String mode = request.getParameter("mode");

		// 获取业务逻辑对象
		BussinessService service = new BussinessServiceImpl();
		// 查询所有流拍的物品
		List<ItemBean> items = service.getFailItems();
		
		if("android".equals(mode)){
			//返回json数据提供给客户端
			JSONArray jsonArray = new JSONArray(items);
			response.getWriter().println(jsonArray.toString());

		}else if("web".equals(mode)){
			//将数据保存在request域中,显示在服务端界面上
			request.setAttribute("items", items);
			request.getRequestDispatcher("/manage/viewFail.jsp").forward(
					request, response);
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
运行效果:

返回json对象:


在客户端上写浏览流拍物品功能:
view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/sub_title_margin"
        android:gravity="center"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/view_titile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/view_succ"
            android:textSize="@dimen/label_font_size" />
        <!-- 定义返回按钮 -->

        <Button
            android:id="@+id/bn_home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/label_font_size"
            android:background="@drawable/home" />
    </LinearLayout>
    <!-- 查看物品列表的ListView -->

    <ListView
        android:id="@+id/succList"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
res/drawable/tv_bg.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
	android:shape="rectangle">
	<stroke android:color="#888"
	    android:width="2dp"/>
	<!-- 设置圆角矩形 -->
	<corners android:radius="2dp" /> 
	<solid android:color="#fff"/>
</shape>
res/values/styles.xml
 <style name="tv_show">
        <item name="android:textColor">#000</item>
        <item name="android:textSize">20sp</item>
        <item name="android:padding">4dp</item>
        <item name="android:background">@drawable/tv_bg</item>
    </style>
ViewItemFragment.java
package com.xbmu.auction.fragment;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.xbmu.auction.R;
import com.xbmu.auction.adapter.JSONArrayAdapter;
import com.xbmu.auction.listener.HomeListener;
import com.xbmu.auction.util.DialogUtil;
import com.xbmu.auction.util.HttpUtil;
public class ViewItemFragment extends Fragment
{
	Button bnHome;
	ListView succList;
	TextView viewTitle;
	@Override
	public View onCreateView(LayoutInflater inflater
		, ViewGroup container, Bundle savedInstanceState)
	{
		View rootView = inflater.inflate(R.layout.view_item
			, container , false);
		// 获取界面上的返回按钮
		bnHome = (Button) rootView.findViewById(R.id.bn_home);
		succList = (ListView) rootView.findViewById(R.id.succList);
		viewTitle = (TextView) rootView.findViewById(R.id.view_titile);
		
		// 为返回按钮的单击事件绑定事件监听器
		bnHome.setOnClickListener(new HomeListener(getActivity()));
		
		//Bundle.getArguments():如果有的话,当fragment初始化的时候,返回提供的参数。
		String action = getArguments().getString("action");
		// 定义发送请求的URL
		String url = HttpUtil.BASE_URL + action+"?mode=android";
		// 如果是查看流拍物品,修改标题
		if (action.equals("viewFail.jsp"))
		{
			viewTitle.setText(R.string.view_fail);
		}
		try
		{
			// 向指定URL发送请求,并把服务器响应转换成JSONArray对象
			JSONArray jsonArray = new JSONArray(HttpUtil
				.getRequest(url));  
			// 将JSONArray包装成Adapter
			JSONArrayAdapter adapter = new JSONArrayAdapter(getActivity()
				, jsonArray, "name", true); 
			succList.setAdapter(adapter);
		}
		catch (Exception e)
		{
			DialogUtil.showDialog(getActivity(), "服务器响应异常,请稍后再试!", false);
			e.printStackTrace();
		}
		succList.setOnItemClickListener(new OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
				int position, long id)
			{
				// 查看指定物品的详细情况。
				viewItemDetail(position);
			}
		});
		return rootView;
	}
	private void viewItemDetail(int position)
	{
		// 加载detail.xml界面布局代表的视图
		View detailView = getActivity().getLayoutInflater()
			.inflate(R.layout.detail, null);
		// 获取detail.xml界面布局中的文本框
		TextView itemName = (TextView) detailView
			.findViewById(R.id.itemName);
		TextView itemKind = (TextView) detailView
			.findViewById(R.id.itemKind);
		TextView maxPrice = (TextView) detailView
			.findViewById(R.id.maxPrice);
		TextView itemRemark = (TextView) detailView
			.findViewById(R.id.itemRemark);
		// 获取被单击的列表项
		JSONObject jsonObj = (JSONObject) succList.getAdapter().getItem(
			position);
		try
		{
			// 通过文本框显示物品详情
			itemName.setText(jsonObj.getString("name"));
			itemKind.setText(jsonObj.getString("kind"));
			maxPrice.setText(jsonObj.getString("maxPrice"));
			itemRemark.setText(jsonObj.getString("desc"));
		}
		catch (JSONException e)
		{
			e.printStackTrace();
		}
		DialogUtil.showDialog(getActivity(), detailView);
	}
}
detail.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:stretchColumns="1" >

    <TableRow>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/item_name"
            android:textSize="@dimen/label_font_size" />

        <TextView
            android:id="@+id/itemName"
            style="@style/tv_show"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </TableRow>

    <TableRow>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/item_kind"
            android:textSize="@dimen/label_font_size" />

        <TextView
            android:id="@+id/itemKind"
            style="@style/tv_show"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </TableRow>

    <TableRow>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/win_price"
            android:textSize="@dimen/label_font_size" />

        <TextView
            android:id="@+id/maxPrice"
            style="@style/tv_show"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </TableRow>

    <TableRow>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/remark"
            android:textSize="@dimen/label_font_size" />

        <TextView
            android:id="@+id/itemRemark"
            style="@style/tv_show"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </TableRow>

</TableLayout>
HomeListener.java
package com.xbmu.auction.listener;

import com.xbmu.auction.AuctionClientActivity;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;

public class HomeListener implements OnClickListener
{
	private Activity activity;
	public HomeListener(Activity activity)
	{
		this.activity = activity;
	}
	@Override
	public void onClick(View source)
	{
		Intent i = new Intent(activity , AuctionClientActivity.class);
		i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		activity.startActivity(i);
	}
}
JSONArrayAdapter.java
package com.xbmu.auction.adapter;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import com.xbmu.auction.R;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class JSONArrayAdapter extends BaseAdapter
{
	private Context ctx;
	// 定义需要包装的JSONArray对象
	private JSONArray jsonArray;
	// 定义列表项显示JSONObject对象的哪个属性
	private String property;
	private boolean hasIcon;
	public JSONArrayAdapter(Context ctx
		, JSONArray jsonArray, String property
		, boolean hasIcon)
	{
		this.ctx = ctx;
		this.jsonArray = jsonArray;
		this.property = property;
		this.hasIcon = hasIcon;
	}

	@Override
	public int getCount()
	{
		return jsonArray.length();
	}

	@Override
	public Object getItem(int position)
	{
		return jsonArray.optJSONObject(position);
	}

	@Override
	public long getItemId(int position)
	{
		try
		{
			// 返回物品的ID
			return ((JSONObject)getItem(position)).getInt("id");
		}
		catch (JSONException e)
		{
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		// 定义一个线性布局管理器
		LinearLayout linear = new LinearLayout(ctx);
		// 设置为水平的线性布局管理器
		linear.setOrientation(0);
		// 创建一个ImageView
		ImageView iv = new ImageView(ctx);
		iv.setPadding(10, 0, 20, 0);
		iv.setImageResource(R.drawable.item);
		// 将图片添加到LinearLayout中
		linear.addView(iv);
		// 创建一个TextView
		TextView tv = new TextView(ctx);
		try
		{
			// 获取JSONArray数组元素的property属性
			String itemName = ((JSONObject)getItem(position))
				.getString(property);
			// 设置TextView所显示的内容
			tv.setText(itemName);
		}
		catch (JSONException e)
		{
			e.printStackTrace();
		}

		tv.setTextSize(20);
		if (hasIcon)
		{
			// 将TextView添加到LinearLayout中
			linear.addView(tv);
			return linear;
		}
		else
		{
			return tv;
		}
	}
}
ViewItem.java
package com.xbmu.auction.activity;

import android.app.Fragment;
import android.os.Bundle;
import com.xbmu.auction.FragmentActivity;
import com.xbmu.auction.fragment.ViewItemFragment;

/**
 * 浏览流拍物品
 * 
 * @author Administrator
 */
public class ViewItem extends FragmentActivity {
	// 重写getFragment()方法,该Activity显示该方法返回的Fragment
	@Override
	protected Fragment getFragment() {
		/**
		 * 思路:Activity向Fragment传递数据:在Activity中创建Bundle数据包,
		 * 并调用Fragment的setArguments(Bundle bundle) 方法即可将Bundle数据包传给Fragment。
		 */
		ViewItemFragment fragment = new ViewItemFragment();
		// 携带数据的数据包对象
		Bundle arguments = new Bundle();
		// 向数据包对象中装数据
		arguments.putString("action", getIntent().getStringExtra("action"));
		//将Bundle数据包传给Fragment
		fragment.setArguments(arguments);
		return fragment;
	}
}
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="action_settings">Settings</string>
    <string name="app_name">电子拍卖</string>
    <string name="welcome">欢迎使用电子拍卖系统</string>
    <string name="hello_world">Hello world!</string>
    <string name="user_name">用户账号:</string>
    <string name="user_pass">用户密码</string>
    <string name="login">登录</string>
    <string name="cancel">取消</string>
    <string name="hello">Hello World, Login!</string>
    <string name="manage_kind">系统的所有物品种类</string>
    <string name="manage_item">你当前的拍卖物品</string>
    <string name="view_bid">你参与竞标的物品</string>
    <string name="choose_kind">请选择一个物品的种类</string>
    <string name="view_succ">浏览竞得物品</string>
    <string name="view_fail">浏览流拍物品</string>
    <string name="item_list">当前种类的物品</string>
	<string name="item_name">物品名:</string>
	<string name="item_kind">物品种类:</string>
	<string name="item_desc">物品描述:</string>
	<string name="win_price">赢取价格:</string>
	<string name="max_price">最高竞价:</string>
	<string name="remark">物品备注:</string>

</resources>
res/vaalues/dimens.xml
<resources>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="title_padding">10dp</dimen>
    <dimen name="label_font_size">20dp</dimen>
    <dimen name="sub_title_margin">20dp</dimen>

</resources>
运行效果:



2018-04-16 01:30:17 byhook 阅读数 611
  • Android移植基础

    Android视频课程,该课程可以让学员了解Android系统架构、学习如何下载Android源码、编译及开发Android、学习如何追踪Android源码、了解Linux内核启动流程、了解Android启动流程、学习如何移植外部函式库至Android源码中。

    26300 人正在学习 去看看 钟文昌

通过前面的文章,Android系统源代码编译成功后,我们开始植入第一个应用程序到系统中去。
首先进入到系统源代码目录,在packages/experimental目录下
新建项目AndyCode,目录结构如下:

MainActivity.java源代码

package com.byhook.andy;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

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

activity_main.xml内容如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.byhook.andy.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
	android:padding="25dp"
        android:text="@string/app_hello"
	android:gravity="center"
        />

</FrameLayout>

strings.xml内容如下:

<resources>
    <string name="app_name">AndyCode</string>
    <string name="app_hello">Hello World!</string>
</resources>

AndroidManifest.xml文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.byhook.andy" >
    android:versionCode="1"
    android:versionName="1.0.0"
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true" >
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

最后一个Android.mk文件内容如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := AndyCode
include $(BUILD_PACKAGE)

开始单独编译应用程序:
source build/envsetup.sh
mmm packages/experimental/AndyCode
编译成功之后,重新打包android系统镜像文件system.img
make snod
启动模拟器
emulator &
可以看到我们的应用程序已经打包进去了

打开应用程序

小结:

之前看过《Android源代码情景分析》这本书,但是遗憾并没有将其记录沉淀下来,最近决定重新温习一下,希望能有新的认识和积累,不过原书的源代码还比较老,强烈建议读者使用新的源代码,实例操作。
纸上得来终觉浅,绝知此事要躬行!

2016-10-11 20:05:42 devwang_com 阅读数 293
  • Android移植基础

    Android视频课程,该课程可以让学员了解Android系统架构、学习如何下载Android源码、编译及开发Android、学习如何追踪Android源码、了解Linux内核启动流程、了解Android启动流程、学习如何移植外部函式库至Android源码中。

    26300 人正在学习 去看看 钟文昌

android源代码分享


android-2.3、android-4.1、android-4.2、android-4.3、android-4.4、android-5.0、android-6.0、android-7.0


百度云分享:


http://pan.baidu.com/s/1dEW7j9J

2017-07-04 19:02:23 JAZZSOLDIER 阅读数 552
  • Android移植基础

    Android视频课程,该课程可以让学员了解Android系统架构、学习如何下载Android源码、编译及开发Android、学习如何追踪Android源码、了解Linux内核启动流程、了解Android启动流程、学习如何移植外部函式库至Android源码中。

    26300 人正在学习 去看看 钟文昌

有时研究 Android 某个特性或者协议的时候需要参阅安卓系统源代码中代码实现或者协议文档等。通过正常的建立 repo,git 获取十分耗时,并且速度很慢,除非是需要重新编译系统,定制系统才需要这样做。因此,推荐一个 Android 系统网站,可以轻松访问,下载参考需要的文档即可。

首先进入网站:http://www.androidxref.com ,界面如下所示:

之后选择我们需要的 Android 版本,以安卓 4.4 为例,点击进入:

此时可以搜索或者直接点击红框中 xref/ 查看源码树,进入源码树后,进入相关目录查看或者下载相关文件即可。比如,这里我想下载 Android ADB 协议文档,进入路径为:

/system/core/adb,然后选择 protocol.txt 文档就可以了,如下所示:




Android源码下载

阅读数 225

Android-源代码分析

阅读数 345

没有更多推荐了,返回首页