其中三个按钮包含三个逻辑
当然也包含几个小知识点:
MainActivity:MVC中的view部分
主要逻辑是根据枚举类型调用NewsManager(操作Controller)返回list,通过handler传给主线程(ui线程)并用listview显示出来
public class MainActivity extends AppCompatActivity {
private ListView lv_newsList;
private NewsManager newsManager;
private Handler handler=new Handler(){
@Override
public void handleMessage( Message msg) {
newsList = (List<NewsInfo>) msg.obj;
lv_newsList.setAdapter(new NewsAdapter(newsList,MainActivity.this));
}
};
private SharedPreferences sp;
private List<NewsInfo> newsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
String type = sp.getString("type",SourceType.SOURCE_FROM_SERVER.getType());
String path = sp.getString("path", AppProperties.SERVER_PATH);
showNewsList(path,SourceType.valueOf(type));
intent();
}
private void intent() {
lv_newsList.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent();
NewsInfo newsInfo =newsList.get(position);
intent.putExtra(AppProperties.NEWS_INTENT_NAME,newsInfo);
intent.setClass(MainActivity.this, ResultActivity.class);
startActivity(intent);
}
});
}
private void initData() {
sp = getSharedPreferences("news", MODE_PRIVATE);
newsManager = new NewsManager();
}
private void initView() {
lv_newsList = (ListView) findViewById(R.id.lv_newsList);
}
public void click(View view) {
SharedPreferences.Editor edit = this.sp.edit();
switch (view.getId()){
case R.id.btn_server:
edit.putString("type",SourceType.SOURCE_FROM_SERVER.getType());
edit.putString("path",AppProperties.SERVER_PATH);
showNewsList(AppProperties.SERVER_PATH,SourceType.SOURCE_FROM_SERVER);
break;
case R.id.btn_asset:
edit.putString("type",SourceType.SOURCE_FROM_ASSETSS.getType());
edit.putString("path",AppProperties.ASSETS_FILE_PATH);
showNewsList(AppProperties.ASSETS_FILE_PATH,SourceType.SOURCE_FROM_ASSETSS);
break;
case R.id.btn_db:
edit.putString("type",SourceType.SOURCE_FROM_DB.getType());
edit.putString("path","");
showNewsList(null,SourceType.SOURCE_FROM_DB);
break;
}
edit.commit();
}
private void showNewsList(final String path, final SourceType sourceType) {
new Thread(){
@Override
public void run() {
List<NewsInfo> newsList = newsManager.getNewsListFromSource(MainActivity.this,sourceType,path);
Message msg = Message.obtain();
msg.obj = newsList;
handler.sendMessage(msg);
}
}.start();
}
}
NewsManager:通过manager管理项目的逻辑部分
根据枚举判断按钮的点击,前两个按钮都有一个共同的功能点,就是获得输入流,一个是从网络端一个是从资源文件,这里定义了一个接口iSource
(Controller这一层是view和model的桥梁, 同时也管理应用逻辑)
public class NewsManager {
public List<NewsInfo>getNewsListFromSource(Context context, SourceType sourceType, String path){
List<NewsInfo>newsList = null;
switch (sourceType){
case SOURCE_FROM_SERVER:
case SOURCE_FROM_ASSETSS:
newsList = getNewsListFromInputStream(context, sourceType, path);
break;
case SOURCE_INTENT:
break;
case SOURCE_FROM_DB:
newsList = new NewsSqlOP(context).queryNewsList();
break;
default:
newsList = new ArrayList<>();
break;
}
return newsList;
}
private List<NewsInfo> getNewsListFromInputStream(Context context,SourceType sourceType, String path) {
List<NewsInfo>newsList= new ArrayList<>();
InputStream in=null;
try {
ISource iSource = SourceFactory.sourceCreate(context, sourceType);
in=iSource.getInputStream(path);
newsList = NewsXmlParser.parse(in);
saveNewsInfo2DB(context,newsList);
} catch (IOException e) {
e.printStackTrace();
} catch (ErrorResponseCodeException e) {
e.printStackTrace();
}finally {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return newsList;
}
private void saveNewsInfo2DB(final Context context, final List<NewsInfo>newsList) {
new Thread(){
@Override
public void run() {
NewsSqlOP newsSqlOP = new NewsSqlOP(context);
int counter= 0;
while (!newsSqlOP.insertWithException(newsList)){
System.out.println("--------failed");
if (counter++ == 3)
break;
}
if (counter!=4)
System.out.println("success");
}
}.start();
}
}
public interface ISource {
InputStream getInputStream(String path) throws IOException, ErrorResponseCodeException;
}
public class SourceMap {
private static HashMap<SourceType,ISource>sourceMap;
public static HashMap<SourceType,ISource> getrateSource(Context context){
if (sourceMap ==null){
sourceMap = new HashMap<>();
sourceMap.put(SourceType.SOURCE_FROM_SERVER,new HttpStreamOP());
sourceMap.put(SourceType.SOURCE_FROM_ASSETSS,new AssetssStreamOP(context));
}
return sourceMap;
}
}
public class HttpStreamOP implements ISource {
@Override
public InputStream getInputStream(String path) throws IOException, ErrorResponseCodeException {
InputStream in = null;
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
int code = connection.getResponseCode();
if (code == 200) {
in = connection.getInputStream();
} else {
throw new ErrorResponseCodeException("error request code is"+ code);
}
return in;
}
}
public class AssetssStreamOP implements ISource {
private Context context;
public AssetssStreamOP(Context context){
this.context=context;
}
@Override
public InputStream getInputStream(String path) throws IOException {
return this.context.getAssets().open(path);
}
}
采用了base64加密和bitmap的压缩
base64应用原因
1.转换成的字符串没有特殊字符
2.加密好的也是唯一的,不能重复
3.加密后的固定长度
public class ImageCache {
private Context context;
public ImageCache(Context context){
this.context=context;
}
public Bitmap getBitmapFromUrl(String path){
File file = new File(this.context.getCacheDir(), Base64.encodeToString(path.getBytes(),Base64.DEFAULT));
if (file.exists() && file.length() >0){
}else {
try {
InputStream inputStream = new HttpStreamOP().getInputStream(path);
if (inputStream != null){
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
writeImage2Cache(bitmap,file);
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
} catch (ErrorResponseCodeException e) {
e.printStackTrace();
return BitmapFactory.decodeResource(this.context.getResources(), R.mipmap.load_failure);
}
}
return BitmapFactory.decodeFile(file.getAbsolutePath());
}
private void writeImage2Cache(final Bitmap bitmap, final File file) {
if(bitmap == null || file == null)
return;
new Thread(){
@Override
public void run() {
BufferedOutputStream bufferedOutputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileOutputStream= new FileOutputStream(file);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream,2*1024);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bufferedOutputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
try {
bufferedOutputStream.flush();
bufferedOutputStream.close();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
}
}
滴滴,以上就是项目的主要部分,包含了许多的基础小知识点
github链接:https://github.com/871924230jp/Mytest
只是记录学习过程 若有错误 欢迎大佬指出