我学习android的时间也有了一段时间,之前一直忙于视频问题的解决,关于android的一些功能还是需要慢慢的去学习,学习了一些东西还是需要静下心来总结和分析的。
最近在做一个简单的应用,为之前的设备制作一个配置的功能,其实该功能的作用很简单就是为了在产品出厂前或者交给客户前能够通过设定一些简单的配置用来验证设备的正确性。
基本的思路如下所示:
设备(后台PHP文件,结果输出JSON)
|
http通信
|
APP (显示配置和添加配置信息)
今天主要就这周在工作中遇到的问题进行说明,以上就是基本的形式。
工作有时候真的是解决问题,并不需要你对知识有多么的透彻,其实从上面的实现,完全可以采用原来的socket直接通信,当然http也是socket。但是在java的世界里采用http更多,不需要关注底层的那些处理。这种处理的方式相比原来的C语言开发来的更直接快捷。当然也留下了很多的坑等着我去跳。PHP的编写,如何将shell的输出转换为json格式都是需要慢慢的摸索的,这些东西只能说用于解决问题,没有进行深入的学习。
在这个项目中APP部分主要就是配置信息的列表(ListView)显示,以及一些配置信息的选择(下拉列表Spinner)的使用,当然还有Http相关的的处理。
在使用ListView等空间的过程中必然会接触到的一个术语是适配器,关于适配器的一些说明已经有很多的文档,主要实现了UI和数据的分离,其实在实际使用中我认为最好用的adapter就是SimpleAdapter,该适配器能解决基本能够解决大部分的问题。特别是在一些常见空间中出现不好处理的情况下都可以采用该适配器,
关于SimpleAdapter我通常使用在当Item布局中存在一些非内容控件(按键等)实现,当然其他的空间也可以实现。在Item布局中存在按键,在需要对某个Item的处理进行定义时可采用如下的方式:
-
listview = (ListView)getActivity().findViewById(R.id.listview);
-
simpleadapter = new SsidlistAdapter(getActivity(), list, R.layout.ssiditem,
-
new String[] {"TYPE", "WLAN_ID", "NAME"},
-
new int[] {R.id.item_ssid_type, R.id.item_wlan_id, R.id.item_ssid_name});
-
-
listview.setAdapter(simpleadapter);
-
-
-
-
class SsidlistAdapter extends SimpleAdapter {
-
-
public SsidlistAdapter(Context context,
-
List<? extends Map<String, ?>> data, int resource,
-
String[] from, int[] to) {
-
super(context, data, resource, from, to);
-
}
-
-
@Override
-
public View getView(int position, View convertView, ViewGroup parent) {
-
final View view = super.getView(position, convertView, parent);
-
Button button = (Button)view.findViewById(R.id.item_delete_btn);
-
button.setOnClickListener(new OnClickListener() {
-
public void onClick(View V) {
-
TextView wlan_id_view = (TextView)view.findViewById(R.id.item_wlan_id);
-
String wlan_id = wlan_id_view.getText().toString();
-
TextView ssid_type_view = (TextView)view.findViewById(R.id.item_ssid_type);
-
String ssid_type = ssid_type_view.getText().toString();
-
-
/* 删除对应的信息 */
-
-
String url = null;
-
if (ssid_type.equals("5.8g") == true) {
-
url = UrlProx + "action=del&arg0=wifi&type=5g&wlan_id=" + wlan_id;
-
} else {
-
url = UrlProx + "action=del&arg0=wifi&type=2g&wlan_id=" + wlan_id;
-
}
-
-
LogUtil.d(TAG, "Delete ssid url: " + url);
-
-
SSidTask task = new SSidTask(TAG);
-
task.execute(url);
-
}
-
});
-
-
return view;
-
}
-
}
基本的实现方法是重新创建一个SimpleAdapter的子类,然后在该类中对Item对象的其他非内容控件设定对应的方法和操作。
ArrayAdapter的使用主要是针对一些简单的控件。spinner就可以采用ArrayAdapter来实现。
-
ssid_type = (Spinner)add_dialog.findViewById(R.id.ssid_type);
-
String[] mItems = getResources().getStringArray(R.array.ssid_type);
-
ArrayAdapter<String> ssid_adapter = new ArrayAdapter<String>(getActivity(),
-
android.R.layout.simple_spinner_item, mItems);
-
ssid_type.setAdapter(ssid_adapter);
-
ssid_type.setOnItemSelectedListener(new OnItemSelectedListener() {
-
-
@Override
-
public void onItemSelected(AdapterView<?> parent,
-
View view, int position, long id) {
-
// TODO Auto-generated method stub
-
-
select_ssid_type = parent.getItemAtPosition(position).toString();
-
LogUtil.d(TAG, "select item: " + select_ssid_type);
-
}
-
-
@Override
-
public void onNothingSelected(AdapterView<?> parent) {
-
// TODO Auto-generated method stub
-
-
-
}
-
-
});
上面就是一段采用adapter和spinner结合使用的例子。
AsyncTask的使用,在UI线程中不能执行复杂的操作,在进行费时操作的过程中通常都采用多线程的方式,在其他线程中不能直接更新UI空间,但是可以采用Handler的形式,这种形式通常是采用发送message的方式实现,这种操作的方式说实在的比较复杂,当然也比较直观。使用AsyncTask的方式能解决这种定义handler的方式,该类的好处是能够对UI空间进行操作和控制。
从上面的实现可知,我们需要实现一个与服务器交互的过程,该交互过程可能很费时,而且配置设备的操作也会占用时间,这在android的UI线程中是不允许的。AsyncTask类中提供了准备函数、后台执行的操作,过程监控函数、执行完成函数。通过重写这些函数就能较好的控制UI和后台操作。我在实现功能的过程中简单的实现了其中的两个函数,后台执行函数和执行完成函数,通过这两个函数的协作,完成app端配置显示的更新。
-
public class HttpUtil extends AsyncTask<String, Void, String> {
-
private String TAG;
-
-
public HttpUtil(String TAG) {
-
this.TAG = TAG;
-
}
-
-
@SuppressWarnings("finally")
-
protected String doInBackground(String ...params) {
-
HttpURLConnection connection = null;
-
String result = null;
-
try {
-
URL url = new URL(params[0]);
-
connection = (HttpURLConnection)url.openConnection();
-
connection.setRequestMethod("GET");
-
connection.setConnectTimeout(8000);
-
connection.setReadTimeout(8000);
-
connection.setDoInput(true);
-
-
InputStream in = connection.getInputStream();
-
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-
-
StringBuilder response = new StringBuilder();
-
String line;
-
-
while ((line = reader.readLine()) != null) {
-
response.append(line);
-
}
-
-
if (response.length() != 0) {
-
result = response.toString();
-
}
-
} catch (FileNotFoundException e) {
-
LogUtil.d(TAG, "FileNotFoundException occured.");
-
e.printStackTrace();
-
} catch (Exception e) {
-
LogUtil.d(TAG, "connection to url: " + params[0] + "failed" );
-
e.printStackTrace();
-
} finally {
-
if (connection != null) {
-
connection.disconnect();
-
}
-
-
return result;
-
}
-
}
-
-
@Override
-
protected void onPostExecute(String result) {
-
LogUtil.d(TAG, "result = " + result);
-
}
-
-
}
该类主要完成了http的get方法获取服务器的数据,将服务器的内容传递给onPostExecute执行,该类只是实现了获取数据的操作,关于后期的解析操作留给具体的业务完成。AsyncTask中的三个类型主要用来说明不同函数的返回值或者操作类型。在使用时去选择合适的参数类型。
其实AsyncTask在解决网络下载等问题时非常的有效,减少了发送message的操作,很多下载监控的实现都是基于该类完成的。建议在有关于网络处理的情况下采用如上的形式定义类,将具体业务的实现由业务去重载。
阅读(10835) | 评论(0) | 转发(2) |