Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 新聞網絡版

新聞網絡版

編輯:關於Android編程

一、---框架---

首先還是來把總體的編碼流程來樹梳理一下,按照這個順序來編碼可以使思路更加清晰。

(1)創建兩個View,一個listview一個item_view

(2)根據view的id來找到listview

(3)從數據庫獲得數據


<1>創建一個包含News數據信息的bean,bean中包含image、title、url和content等

<2>有了news的bean就應該有操作bean的Utils,這裡創建一個NewsUtils類

<3>NewsUtils的作用就是獲取新聞數據的,裡面主要有兩個方法:getAllNewsForNetWork和getAllNewsForDatabase

<4>網絡那個後面說,從數據庫中得到首先要有數據庫和他的操作類,創建NewsOpenHelper和NewsDaoUtils

<5>NewsOpenHelper是數據庫的幫助類,NewsDaoUtils中定義增刪改查的方法

<6>流程是NewsUtils.getAllNewsForDatabase()->NewsDaoUtils.getNews()

(4)將數據傳給item_view並做顯示


<1>通過上面的步驟得到ArrayList類型的新聞數據,下面是在ListView中展示了

<2>ListView使用要通過一個Adapter類,我們定義一個NewsAdapter類並實現其四個覆寫BaseAdapter的四個方法

<3>在NewsAdapter中的getView()中將我們定義好的item_view布局並將其轉換成一個view,並根據面得到的數據來給view

的各個控件賦值


(5)從網絡端獲取數據,並將數據庫中的數據更新


<1>上面也提到了,通過網絡獲取數據,在NewsUtils中定義getAllNewsForNewWork

<2>也就是通過網絡訪問服務器中GetNewsServlet,實現輸入流和輸出流的對接,當然這邊是輸入流了

<3>將得到的流通過StreamUtils.streamToString()轉化成字符串

<4>因為數據是json格式的,所以需要先轉化成json對象再進行解析,最終編程ArrayList

<5>注意在返回數據之前,先將數據庫清空,然後將數據緩存到裡邊

<6>回到主函數,因為主線程中不能處理時間過長的時間,所以要建立一個子線程獲取網絡數據

<7>建立一個主線程來進行ListView的展示


(6)當有事件點擊時的跳轉


<1>當有點擊事件時,跳轉到news_url

(7)smartimageview 的原理

<1>自定義了一個MyImageview類繼承了Imageview,添加三個構造方法

<2>添加一個setImageUrl方法接受一個圖片url

<3>新建一個子線程去請求url獲取圖片資源

<4>將獲取的圖片Bitmap通過handler發送給主線程,主線程設置給當前view

<5>在布局中引用MyImageview,需要指定完成的包名路徑。

二、---ListView布局---

Activity中就只有一個ListView就不展示了,下面是item_news_layout.xml 的代碼

使用線性和相對布局相結合的方式了就行布局,包括標題、內容、圖片和評論等

 




    

    

        

        

        

            

            
        
    


 

 

 

三、---獲得數據庫數據---

(1)創建一個包含News數據信息的bean,bean中包含image、title、url和content等

package com.iigt.Internews.bean;

public class NewsBean {

	public String title;
	public String des;
	public String news_url;
	public int id;
	public int comment;
	public int type;
	public String time;
	public String icon_url;
	
}

 


(2)有了news的bean就應該有操作bean的Utils,這裡創建一個NewsUtils類

 

package com.iigt.Internews.utils;

public class NewsUtils {

	public static String newsPath_url = "http://115.25.200.156:8080/itheima74/servlet/GetNewsServlet";
	//封裝新聞的假數據到list中返回
	public static ArrayList getAllNewsForNetWork(Context context) 

	
	//從數據庫中獲取上次緩存的新聞數據做listview的展示
	public static ArrayList getAllNewsForDatabase(Context context) 
}
(3)NewsUtils的作用就是獲取新聞數據的,裡面主要有兩個方法:getAllNewsForNetWork和getAllNewsForDatabase

 

 

	//從數據庫中獲取上次緩存的新聞數據做listview的展示
	public static ArrayList getAllNewsForDatabase(Context context) {
		
		return new NewsDaoUtils(context).getNews();
	}

(4)網絡那個後面說,從數據庫中得到首先要有數據庫和他的操作類,創建NewsOpenHelper和NewsDaoUtils

 

 

package com.iigt.Internews.dao;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class NewsOpenHelper extends SQLiteOpenHelper {

	public NewsOpenHelper(Context context) {
		super(context, "heimanews1", null, 1);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
/*		newsJson.put("id", newsBean.getId());
		newsJson.put("title", newsBean.getTitle());
		newsJson.put("des", newsBean.getDes());
		newsJson.put("icon_url", newsBean.getIcon_url());
		newsJson.put("news_url", newsBean.getNews_url());
		newsJson.put("type", newsBean.getType());
		newsJson.put("time", newsBean.getTime());
		newsJson.put("comment", newsBean.getComment());*/
		db.execSQL("create table news (_id integer  ,title varchar(200),des varchar(300),icon_url varchar(200),news_url varchar(200)," +
				" type integer , time varchar(100),comment integer)");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub

	}

}


(5)NewsOpenHelper是數據庫的幫助類,NewsDaoUtils中定義增刪改查的方法

 

 

package com.iigt.Internews.dao;

import java.util.ArrayList;

import com.iigt.Internews.bean.NewsBean;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class NewsDaoUtils {

	private NewsOpenHelper newsOpenHelper;

	public NewsDaoUtils(Context context){

		//創建一個幫助類對象
		newsOpenHelper = new NewsOpenHelper(context);
	}

	//刪除數據庫中緩存的舊數據
	public void delete(){

		//通過幫助類對象獲取一個數據庫操作對象
		SQLiteDatabase db = newsOpenHelper.getReadableDatabase();
		db.delete("news", null, null);
		db.close();
	}

	//向數據庫中添加新聞數據
	public void saveNews(ArrayList list){

		//通過幫助類對象獲取一個數據庫操作對象
		SQLiteDatabase db = newsOpenHelper.getReadableDatabase();
		for (NewsBean newsBean : list) {
			ContentValues values = new ContentValues();
			values.put("_id", newsBean.id);
			values.put("title", newsBean.title);
			values.put("des", newsBean.des);
			values.put("icon_url", newsBean.icon_url);
			values.put("news_url", newsBean.news_url);
			values.put("type", newsBean.type);
			values.put("time", newsBean.time);
			values.put("comment", newsBean.comment);
			db.insert("news", null, values);
		}

		db.close();
	}

	//從數據庫中獲取緩存的新聞數據
	public ArrayList getNews(){
		ArrayList list = new ArrayList();
		//通過幫助類對象獲取一個數據庫操作對象
		SQLiteDatabase db = newsOpenHelper.getReadableDatabase();
		Cursor cursor = db.rawQuery("select * from news", null);//查詢獲取數據

		if(cursor != null && cursor.getCount() > 0){

			while(cursor.moveToNext()){

				NewsBean newsBean = new NewsBean();
				newsBean. id = cursor.getInt(0);
				newsBean. title = cursor.getString(1);
				newsBean. des =	cursor.getString(2);
				newsBean. icon_url =	cursor.getString(3);
				newsBean. news_url =	cursor.getString(4);
				newsBean. 	type = cursor.getInt(5);
				newsBean. time =	cursor.getString(6);
				newsBean. 	comment = cursor.getInt(7);

				list.add(newsBean);
			}
		}

		db.close();
		cursor.close();

		return list;

	}



}
其獲取數據的流程是NewsUtils.getAllNewsForDatabase()->NewsDaoUtils.getNews()

 

 

四、---數據控件顯示---

(1)通過上面的步驟得到ArrayList類型的新聞數據,下面是在ListView中展示了

 

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mContext = this;
		lv_news = (ListView) findViewById(R.id.lv_news);

		//1.先去數據庫中獲取緩存的新聞數據展示到listview
		ArrayList allnews_database = NewsUtils.getAllNewsForDatabase(mContext);

		if(allnews_database !=null && allnews_database.size()>0){
			//創建一個adapter設置給listview
			NewsAdapter newsAdapter = new NewsAdapter(mContext, allnews_database);
			lv_news.setAdapter(newsAdapter);
		}

(2)ListView使用要通過一個Adapter類,我們定義一個NewsAdapter類並實現其四個覆寫BaseAdapter的四個方法

 

 

package com.iigt.Internews.adapter;

import java.util.ArrayList;

import com.iigt.Internews.R;
import com.iigt.Internews.bean.NewsBean;
import com.iigt.Internews.view.MyImageView;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class NewsAdapter extends BaseAdapter {
	
	private ArrayList list;
	private Context context;

	//通過構造方法接受要顯示的新聞數據集合
	public NewsAdapter(Context context,ArrayList list){
		this.list = list;
		this.context = context;
	}

	@Override
	public int getCount() {
		return list.size();
	}

	@Override
	public Object getItem(int position) {
		return list.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view = null;
		//1.復用converView優化listview,創建一個view作為getview的返回值用來顯示一個條目
		if(convertView != null){
			view = convertView;
		}else {
			//context:上下文, resource:要轉換成view對象的layout的id, root:將layout用root(ViewGroup)包一層作為codify的返回值,一般傳null
//			view = View.inflate(context, R.layout.item_news_layout, null);//將一個布局文件轉換成一個view對象
			
			//通過LayoutInflater將布局轉換成view對象
//			view =  LayoutInflater.from(context).inflate(R.layout.item_news_layout, null);
			
			//通過context獲取系統服務得到一個LayoutInflater,通過LayoutInflater將一個布局轉換為view對象
			LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			view = layoutInflater.inflate(R.layout.item_news_layout, null);
			
		}
		//2.獲取view上的子控件對象
		MyImageView item_img_icon = (MyImageView) view.findViewById(R.id.item_img_icon);
		TextView item_tv_des = (TextView) view.findViewById(R.id.item_tv_des);
		TextView item_tv_title = (TextView) view.findViewById(R.id.item_tv_title);
		TextView item_tv_comment = (TextView) view.findViewById(R.id.item_tv_comment);
		TextView item_tv_type = (TextView) view.findViewById(R.id.item_tv_type);
		
		
		//3.獲取postion位置條目對應的list集合中的新聞數據,Bean對象
		NewsBean newsBean = list.get(position);
		//4.將數據設置給這些子控件做顯示
		item_img_icon.setImageUrl(newsBean.icon_url);
		item_tv_title.setText(newsBean.title);
		item_tv_des.setText(newsBean.des);
		item_tv_comment.setText("評論:"+newsBean.comment);
		
		//0 :頭條 1 :娛樂 2.體育
		switch (newsBean.type) {
		case 0:
			item_tv_type.setText("頭條");
			break;
		case 1:
			item_tv_type.setText("娛樂 ");
			break;
		case 2:
			item_tv_type.setText("體育");
			break;
		default:
			break;
		}		
		return view;
	}

}
在NewsAdapter中的getView()中將我們定義好的item_view布局並將其轉換成一個view,並根據面得到的數據來給view

 

的各個控件賦值

 

 

五、---網絡獲取數據---

(1)上面也提到了,通過網絡獲取數據,在NewsUtils中定義getAllNewsForNewWork

 

	public static String newsPath_url = "http://115.25.200.156:8080/itheima74/servlet/GetNewsServlet";
	//封裝新聞的假數據到list中返回
	public static ArrayList getAllNewsForNetWork(Context context) {
		ArrayList arrayList = new ArrayList();
		try{
			//1.請求服務器獲取新聞數據
			//獲取一個url對象,通過url對象得到一個urlconnnection對象
			URL url = new URL(newsPath_url);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			//設置連接的方式和超時時間
			connection.setRequestMethod("GET");
			connection.setConnectTimeout(10*1000);
			//獲取請求響應碼
			int code = connection.getResponseCode();
			if(code == 200){
				//獲取請求到的流信息
				InputStream inputStream = connection.getInputStream();
				//將流轉換成字符串
				String result = StreamUtils.streamToString(inputStream);
				
				//2.解析獲取的新聞數據到List集合中。
				
					JSONObject root_json = new JSONObject(result);//將一個字符串封裝成一個json對象。
					JSONArray jsonArray = root_json.getJSONArray("newss");//獲取root_json中的newss作為jsonArray對象
					
					for (int i = 0 ;i < jsonArray.length();i++){//循環遍歷jsonArray
						JSONObject news_json = jsonArray.getJSONObject(i);//獲取一條新聞的json
						
						NewsBean newsBean = new NewsBean();
						
						newsBean. id = news_json.getInt("id");
						newsBean. comment = news_json.getInt("comment");//評論數
						newsBean. type = news_json.getInt("type");//新聞的類型,0 :頭條 1 :娛樂 2.體育
						newsBean. time = news_json.getString("time");
						newsBean. des = news_json.getString("des");
						newsBean. title = news_json.getString("title");
						newsBean. news_url = news_json.getString("news_url");
						newsBean. icon_url = news_json.getString("icon_url");
						
						arrayList.add(newsBean);
			
					}

				//3.清除數據庫中舊的數據,將新的數據緩存到數據庫中
					new NewsDaoUtils(context).delete();
					new NewsDaoUtils(context).saveNews(arrayList);
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		return arrayList;
	}

(2)也就是通過網絡訪問服務器中GetNewsServlet,實現輸入流和輸出流的對接,當然這邊是輸入流了

 

 

package com.itheima.service;

import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;

public class GetNewsServlet extends HttpServlet {

	// 構造方法
	public GetNewsServlet() {
		super();
	}

	// 摧毀這個servlet,不太懂
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}

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

		try{
			ArrayList news = NewsDao.getNews();

			JSONArray jsonArray = new JSONArray();
			for (NewsBean newsBean : news) {
				JSONObject newsJson = new JSONObject();
				newsJson.put("id", newsBean.getId());
				newsJson.put("title", newsBean.getTitle());
				newsJson.put("des", newsBean.getDes());
				newsJson.put("icon_url", newsBean.getIcon_url());
				newsJson.put("news_url", newsBean.getNews_url());
				newsJson.put("type", newsBean.getType());
				newsJson.put("time", newsBean.getTime());
				newsJson.put("comment", newsBean.getComment());
				jsonArray.put(newsJson);

			}

			JSONObject allNewsJson = new JSONObject();
			allNewsJson.put("newss", jsonArray);
			response.getOutputStream().write(allNewsJson.toString().getBytes("gbk"));

		}catch (Exception e) {
		}
	}

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

		doGet(request, response);
	}

	public void init() throws ServletException {
	}

}

(3)將得到的流通過StreamUtils.streamToString()轉化成字符串

 

 

public class StreamUtils {


	public static String streamToString(InputStream  in){
		String result ="";

		try{
			//創建一個字節數組寫入流
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			
			byte[] buffer = new byte[1024];
			int length = 0;
			while (  (length =  in.read(buffer)) !=-1) {
				out.write(buffer, 0, length);
				out.flush();
			}
			
			result =   new String(out.toByteArray(),"gbk");
			
//			result = out.toString();//將字節流轉換成string
			
			out.close();
		}catch (Exception e) {
			e.printStackTrace();
		}


		return result;
	}
}
因為數據是json格式的,所以需要先轉化成json對象再進行解析,最終編程ArrayList

 


(5)注意在返回數據之前,先將數據庫清空,然後將數據緩存到裡邊

 

//3.清除數據庫中舊的數據,將新的數據緩存到數據庫中
new NewsDaoUtils(context).delete();
new NewsDaoUtils(context).saveNews(arrayList);

(6)回到主函數,因為主線程中不能處理時間過長的時間,所以要建立一個子線程獲取網絡數據

 

 

//2.通過網絡獲取服務器上的新聞數據用list封裝 ,獲取網絡數據需要在子線程中做
new Thread(new Runnable() {

	@Override
	public void run() {

		
		//請求網絡數據
		ArrayList allNews = NewsUtils.getAllNewsForNetWork(mContext);
		//通過handler將msg發送到主線程去更新Ui
		Message msg = Message.obtain();
		msg.obj = allNews;
		handler.sendMessage(msg);


	}
}).start();

(7)建立一個主線程來進行ListView的展示

 

private Handler handler = new Handler(){
	public void handleMessage(android.os.Message msg) {

		ArrayList allNews = (ArrayList) msg.obj;

		if(allNews != null && allNews .size()>0)
		{
			//3.創建一個adapter設置給listview
			NewsAdapter newsAdapter = new NewsAdapter(mContext, allNews);
			lv_news.setAdapter(newsAdapter);
		}

	};
};

 

 

 

六、---點擊事件---

點擊事件處理函數

 

	public void onItemClick(AdapterView parent, View view, int position,
			long id) {

		//需要獲取條目上bean對象中url做跳轉
		NewsBean bean = (NewsBean) parent.getItemAtPosition(position);

		String url = bean.news_url;

		//跳轉浏覽器
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_VIEW);
		intent.setData(Uri.parse(url));
		startActivity(intent);
	}

如下是自定義的從網絡上獲取圖片的方法

 

 

public class MyImageView extends ImageView {

	public MyImageView(Context context) {
		super(context);
	}
	public MyImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	public MyImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}
	
	private Handler handler = new Handler(){
		
		public void handleMessage(android.os.Message msg) {
			
			Bitmap bitmap = (Bitmap) msg.obj;
			
			MyImageView.this.setImageBitmap(bitmap);
		};
	};

	public void setImageUrl(final String url_str){
		
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				try{
					//獲取url對應的圖片資源,bitmap
					URL url = new URL(url_str);
					
					HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
					
					openConnection.setRequestMethod("GET");
					openConnection.setConnectTimeout(10*1000);
					
					int code = openConnection.getResponseCode();
					if(code == 200){
						InputStream inputStream = openConnection.getInputStream();
						
						
						Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
						
						Message msg = Message.obtain();
						msg.obj = bitmap;
						handler.sendMessage(msg);	
					}
					
					
				}catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
		
	
	}

}

最後新聞的展示界面如下

 

\

 


 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved