版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Mackyhuang/article/details/82431745
Android
@mackyhuang
环境配置
- JDK的安装
- SDK的安装
- IDEA配置
- genymotion安装
- gradle安装配置
- 项目启动
项目详细
- 主要使用到三个部分的内容
- src/main/java java代码业务逻辑处理部分
- src/main/res/layout 界面UI的存放位置
- Androidmanifest/xml 部分 权限控制/测试配置
项目流程
- 界面设计和代码编写
- XML语言用scheme规范的样式代码
- 业务逻辑代码编写
- MainActivity的完成
- 主要是
- getContentView()
- findViewById()
- setOnClickListener()
- 实现OnClickListener接口
- 实现类中编写点击事件代码
- MainActivity的完成
- 部署到手机上
关于context获取项目路径的方法
- context.getFilesDir().getAbsolutePath() 获取Data/data/包名/files
- content.openFileOutput(name, mode) 直接写入Data/data/包名/files下面
名字是name的文件 mode是private - content.openFileInput(name) 直接读取Data/data/包名/files下面
名字是name的文件
关于sdcard的存取
- mnt/sdcard/.
- 获取目录:Environment.getExternalStorageDirectory().getAbsolutePath() + “/.“;
- 判断sdcard是否可用:Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
获取sdcard空间
File sdcard = Environment.getExternalStorageDirectory();
long freenum = sdcard.getFreeSpace();
long totalnum = sdcard.getTotalSpace();
String free1 = Formatter.formatFileSize(this, freenum);
String total1 = Formatter.formatFileSize(this, totalnum);
free.setText(free1);
total.setText(total1);
Android的单位
- 使用dp替代px
- dp会自动适配手机的屏幕
- 文字的大小需要使用 sp
SharedPreferences的使用 sharedPreference是轻量级的存储api
- 开启应用:sharedPreferences = getSharedPreferences(“指定文件名”, MODE_PRIVATE);
存:
SharedPreferences.Editor editor = sharedPreferences.edit() editor.putString("username", name); editor.putString("password", pwd); editor.commit();
不能忘记commit()
取:
String name = sharedPreferences.getString("username", ""); String pwdname = sharedPreferences.getString("password", "");
- 在项目下 生成一个 shared_prefs文件 里面存着文件
Serializer 生成一个xml
XmlSerializer serializer = Xml.newSerializer();
// 一个输出流 一个编码
serializer.setOutput(openFileOutput("smslist.xml", MODE_PRIVATE), "utf-8");
serializer.startDocument("utf-8", true);
// 第一个null是namespace 因为这里没有scheme 所以不用
serializer.startTag(null, "SMSlist");
for (SMS sms2:sms) {
serializer.startTag(null, "SMS");
serializer.startTag(null, "num");
serializer.text(sms2.num);
serializer.endTag(null, "num");
serializer.startTag(null, "content");
serializer.text(sms2.content);
serializer.endTag(null, "content");
serializer.startTag(null, "time");
serializer.text(sms2.time);
serializer.endTag(null, "time");
serializer.endTag(null, "SMS");
}
serializer.endTag(null, "SMSlist");
serializer.endDocument();
}
解析一个xml
XmlPullParser pullParser = Xml.newPullParser();
pullParser.setInput(openFileInput("smsList.xml", "utf-8));
int evetType = pullParser.getEventType();
while(eventType != XmlPullParser.END_DOCUMENT){
eventType 与 XmlPullParser.START_TAG
}
关于SQLite数据库
事务:
db.beginTransaction();
try{
…
db.setTransactionSuccessful();
}finally{
db.endTransaction();
db.close();
}
Listview 插件
ListView listView = findViewById(R.id.lv_list);
这里需要一个适配器 所以需要实现一个抽象类
listView.setAdapter(new listAdapter());
private class listAdapter extends BaseAdapter{
@Override
public int getCount() {
return 30;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
// 第一个参数 是当前遍历到的对象是第几条 从0开始
// 第二个参数 代表有没有可以重用的对象
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
View itemView = null;
if(view == null){
itemView = View.inflate(MainActivity.this, R.layout.item, null);
// 其他三种办法获取inflate
// LayoutInflater layoutInflater = getSystemService(LAYOUT_INFLATER_SERVICE);
// LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
// LayoutInflater layoutInflater1 = getLayoutInflater();
// layoutInflater.inflate(R.layout.item, null);
}else {
itemView = view;
}
return itemView;
}
}
一个小的简便的 ArrayAdapter
- 适用于小的
- 只有TextView的布局xml
SimpleAdapter
setContentView(R.layout.activity_main); ListView listView = findViewById(R.id.lv_list); List<Map<String, String>> data = new ArrayList<>(); Map<String, String> map1 = new HashMap<>(); Map<String, String> map2 = new HashMap<>(); map1.put("title", "今日要闻1"); map2.put("title", "今日要闻2"); map1.put("content", "背景哈桑当就伸缩"); map2.put("content", "背景哈桑当就伸缩"); data.add(map1); data.add(map2); String[] from = {"title", "content"}; int[] to = new int[]{R.id.tv_title, R.id.tv_content}; SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.item, from, to); listView.setAdapter(simpleAdapter);
网页源代码查看器(web服务连接初体验)
重要的点是 网络的连接(HttpURLConnection)
点击事件源码: public void onClick(View view) { String path = editText.getText().toString().trim(); Log.v("mnb", path); URL url = null; try { url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 设置请求方式 connection.setRequestMethod("GET"); 设置网络请求超时10s connection.setConnectTimeout(10000); 获取响应码 int responseCode = connection.getResponseCode(); Log.v("mnb", responseCode + ""); if(responseCode == 200){ InputStream inputStream = connection.getInputStream(); String tran = ReadUtil.tran(inputStream); textView.setText(tran); }else { Toast.makeText(MainActivity.this, "服务器访问失败", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { e.printStackTrace(); } }
这里有一个版本更新以后,请求http会错误的地方,俩个解决办法,一个是:
setContentView(R.layout.activity_main); if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); }
- 另一个是线程操作,试过以后无法运行,(后面解决了)
其中有一个工具类:
public class ReadUtil { public static String tran(InputStream inputStream) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); int len = -1; byte[] buffer = new byte[1024]; try { while ((len = inputStream.read(buffer)) != -1){ byteArrayOutputStream.write(buffer, 0, len); } byte[] res = byteArrayOutputStream.toByteArray(); return new String(res); } catch (Exception e){ e.printStackTrace(); return null; } } }
ScrollView (包裹需要被滚动的内容) 只能由一个子元素(多个可以用一个大的包)
<ScrollView android:layout_below="@id/btn" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv_text" android:layout_width="match_parent" android:layout_height="match_parent"/> </ScrollView>
一个重要的常识!!!
- 联网的时候 不能主线程中操作,只能在子线程里面操作,因为网速问题会阻塞主线程
- 子线程不能修改UI界面 主线程又叫UI线程
- 所以 子线程里面获取数据,然后把数据交给主线程,主线程修改UI
- 在主线程里面创建一个Handler, 用消息队列来接受子线程传过来的数据
一个Handle的创建
private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { String tran = (String) msg.obj; textView.setText(tran); } };
一个结果的传递
Message message = new Message(); message.obj = tran; handler.sendMessage(message);
- 通过Message来传递消息,然后进行渲染
- 这个消息机制中 靠的是 Looper MessagerQueue Handler Message
- Lopper从子线程不断的拿到消息,然后通过比较when排先后进行执行,执行就到Handler的HandleMessage
简单的runOnUiThread
runOnUiThread(new runnable(){
public void run(){
//这个里面的代码一定会在主线程中执行
}
})