【Android】安卓开发之通过本地广播实现子线程和UI线程的通信
2017-02-26 17:57
701 查看
在做一个demo的时候,需要实现一个效果:当用户进行一些耗时操作的时候,显示一个进度条对话框,避免用户产生程序没反应的体验。而耗时操作一般都是在子线程中进行,而且如果耗时操作在子线程调用的外部类当中,那我们要如何让子线程将消息通知给UI线程,让UI线程及时的显示和收回进度条对话框呢?方法还是有的,比如说使用本地广播。
一、在子线程调用的外部类里,进行本地广播发送设置:
二、在UI线程里进行本地广播接收设置
效果:
一、在子线程调用的外部类里,进行本地广播发送设置:
public class SendPostRequest { //-----------------------------声明一个本地广播管理器------------------------------------------- private LocalBroadcastManager localBroadcastManager; //---------------------------------------------------------------------------------------------- public String sendPostRequest(String url, String param,Context context) { //-------------------------获取本地广播管理器的实例----------------------------------------- localBroadcastManager = LocalBroadcastManager.getInstance(context); //------------------------------------------------------------------------------------------ //-------------------------要发送的广播消息,使用intent作为载体----------------------------- Intent intentEN = new Intent("LOCAL_BROADCAST_EN_PROGRESS_DIALOG"); Intent intentDIS = new Intent("LOCAL_BROADCAST_DIS_PROGRESS_DIALOG"); //------------------------------------------------------------------------------------------ HttpURLConnection httpURLConnection = null; OutputStream out = null; //写 InputStream in = null; //读 int responseCode = 0; //远程主机响应的HTTP状态码 String result = ""; try { URL sendUrl = new URL(url); httpURLConnection = (HttpURLConnection) sendUrl.openConnection(); //post方式请求 httpURLConnection.setRequestMethod("POST"); //设置头部信息 httpURLConnection.setRequestProperty("headerdata", "ceshiyongde"); //一定要设置 Content-Type 要不然服务端接收不到参数 httpURLConnection.setRequestProperty("Content-Type", "application/Json; charset=UTF-8"); //指示应用程序要将数据写入URL连接,其值默认为false(是否传参) httpURLConnection.setDoOutput(true); //httpURLConnection.setDoInput(true); httpURLConnection.setUseCaches(false); //--------------------发送弹出进度条对话框的本地广播------------------------------------ localBroadcastManager.sendBroadcast(intentEN); //-------------------------------------------------------------------------------------- httpURLConnection.setConnectTimeout(5000); //5秒连接超时 httpURLConnection.setReadTimeout(3000); //5秒读取超时 //传入参数 out = httpURLConnection.getOutputStream(); out.write(param.getBytes()); out.flush(); //清空缓冲区,发送数据 out.close(); responseCode = httpURLConnection.getResponseCode(); //获取请求的资源 BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8")); result = br.readLine(); } catch (Exception e) { e.printStackTrace(); } Map<String, String> map = new Gson().fromJson(result, new TypeToken<Map<String, String>>() { }.getType()); String msg = ""; try{ msg = map.get("msg"); }catch (NullPointerException ne){ Log.i("tag","网络连接异常"); } //--------------------发送关闭进度条对话框的本地广播---------------------------------------- localBroadcastManager.sendBroadcast(intentDIS);//后台不开的情况下,读取超时不起作用 //------------------------------------------------------------------------------------------ return msg; } }
二、在UI线程里进行本地广播接收设置
public class RegisterPart2 extends BaseActivity { private final int PASSDIFF = 0; private final int LENLESS = 1; private final int REGSUCCESS = 2; private final int REGEXIST = 3; private final int REGFAIL = 4; private final int EN_PROCESSDIALOG = 5; private final int DIS_PROCESSDIALOG = 6; private String userName; private IntentFilter intentFilter_en; private IntentFilter intentFilter_dis; private LocalReceiver localReceiver; private LocalBroadcastManager lm; AlertDialog.Builder dialog; //对象的获得不能放在Handler里,不然会重复创建,然后指向的不是一个对象,导致进度条对话框无法关闭 ProgressDialog pd; //--------------------------------------------定义一个Handler来处理消息------------------------- final Handler handler = new Handler() { @Override public void handleMessage(Message message) { switch (message.what) { case PASSDIFF: dialog.setMessage("两次输入的密码不一致!"); dialog.setCancelable(false); dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int which) { } }); dialog.show(); break; case LENLESS: dialog.setMessage("密码长度不足8位!"); dialog.setCancelable(false); dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int which) { } }); dialog.show(); break; case REGSUCCESS: dialog.setMessage("注册成功!"); dialog.setCancelable(false); dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int which) { //注册成功则跳转到登陆页面,不成功不跳转 Intent intent = new Intent(RegisterPart2.this, Login.class); startActivity(intent); ActivityCollector.finishAll(); } }); dialog.show(); break; case REGEXIST: dialog.setMessage("注册的账户已经存在!"); dialog.setCancelable(false); dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int which) { } }); dialog.show(); break; case REGFAIL: dialog.setMessage(message.obj+" 一定出了什么问题。。。╮(╯▽╰)╭ "); dialog.setCancelable(false); dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int which) { } }); dialog.show(); break; case EN_PROCESSDIALOG://显示进度条对话框 pd.setCancelable(true); pd.setMessage("请稍候......"); pd.show(); break; case DIS_PROCESSDIALOG://关闭进度条对话框 pd.dismiss(); break; default: break; } } }; //---------------------------------------------------------------------------------------------- @Override protected void onDestroy(){ super.onDestroy(); //---------------------------当活动被销毁时,注销本地广播接收器----------------------------- lm.unregisterReceiver(localReceiver); //------------------------------------------------------------------------------------------ } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.new_register_part2); dialog = new AlertDialog.Builder(RegisterPart2.this);//对话框 pd = new ProgressDialog(RegisterPart2.this);//获取进度条对话框的对象 //---------------------------注册本地广播--------------------------------------------------- intentFilter_en = new IntentFilter(); intentFilter_dis = new IntentFilter(); intentFilter_en.addAction("LOCAL_BROADCAST_EN_PROGRESS_DIALOG"); intentFilter_dis.addAction("LOCAL_BROADCAST_DIS_PROGRESS_DIALOG"); localReceiver = new LocalReceiver();//获取本地广播接收器的对象 lm = LocalBroadcastManager.getInstance(this);//获取本地广播管理器的对象 lm.registerReceiver(localReceiver,intentFilter_en); lm.registerReceiver(localReceiver,intentFilter_dis); //------------------------------------------------------------------------------------------ //---------------------------给状态栏设置颜色----------------------------------------------- TextView textViewActionBar = (TextView) findViewById(R.id.actionBarId); setActionBarColor(textViewActionBar, getResources().getColor(R.color.theRed)); //------------------------------------------------------------------------------------------ //----------------------------使用Intent解析上一个活动传来的数据---------------------------- Intent intent = getIntent(); userName = intent.getStringExtra("userName"); //------------------------------------------------------------------------------------------ final EditText regUserName = (EditText) findViewById(R.id.regist2NameEditId); final EditText regPassword = (EditText) findViewById(R.id.regist2PasswordEditId); final EditText regConfirm = (EditText) findViewById(R.id.regist2ConfirmEditId); EditText regEmail = (EditText) findViewById(R.id.regist2EmailEditId); Button confirmButton = (Button) findViewById(R.id.regist2ConfirmBottonId); /** * 完成注册,销毁之前的注册活动,直接跳到登陆界面,且不可返回之前注册活动 */ confirmButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //----------------------------------收回软键盘-------------------------------------- InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(),0); } //---------------------------------------------------------------------------------- //---------------------通过POST请求将用户名和密码发送给服务器----------------------- try { //新建一个线程,通过Message消息通知Handle对UI进行更改,现在只能在UI线程里对UI组件进行更改。 new Thread(new Runnable() { @Override public void run() { String password = regPassword.getText().toString(); String confirmPassword = regConfirm.getText().toString(); Message message = new Message(); if (!(password.equals(confirmPassword))) {//如果输入的密码不一致 message.what = PASSDIFF; handler.sendMessage(message); return; } if (password.length() < 8) {//如果输入的密码长度小于8位 message.what = LENLESS; handler.sendMessage(message); return; } //下面三句话,将会把三个参数包装为{"para1":10,"para2":2,"opt":"div"}字段 CalBean tb = new CalBean(userName, password); Gson gson = new Gson(); String datas = gson.toJson(tb); String url = " http://10.10.120.43:8080/Register"; SendPostRequest sendPostRequest = new SendPostRequest(); String data = sendPostRequest.sendPostRequest(url,datas,RegisterPart2.this); //根据返回来的数据进行判断是否注册成功 if (data.equals("注册成功")) { message.what = REGSUCCESS; handler.sendMessage(message); return; } else if (data.equals("账户已存在")) { message.what = REGEXIST; handler.sendMessage(message); return; } else { message.what = REGFAIL; message.obj = data.toString(); handler.sendMessage(message); return; } } }).start(); } catch (Exception e) { Log.i("ok", "there must be something wrong!"); return; } //---------------------------------------------------------------------------------- } }); } //------------------------------------重写本地广播接收器---------------------------------------- class LocalReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context,Intent intent){ switch (intent.getAction()){ case "LOCAL_BROADCAST_EN_PROGRESS_DIALOG": Message en_message = new Message(); en_message.what = EN_PROCESSDIALOG; handler.sendMessage(en_message); break; case "LOCAL_BROADCAST_DIS_PROGRESS_DIALOG": Message dis_message = new Message(); dis_message.what = DIS_PROCESSDIALOG; handler.sendMessage(dis_message); break; default:break; } } } //---------------------------------------------------------------------------------------------- }
效果:
相关文章推荐
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法实现边缘检测代码(2)
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
- Android开发(17)-通过安卓API的Tabs3实现仿优酷tabhost效果
- Android开发入门之网络通信(通过HTTP协议实现文件上传)
- 安卓开发中通过广播监听网络状态的代码实现
- 【Android】安卓开发实战之通过visibility属性实现搜索框弹出效果
- Android开发(17)-通过安卓API的Tabs3实现仿优酷tabhost效果
- Android开发之通过AIDL服务实现进程间的通信
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
- Android开发之Service通过Messenger实现线程间的通信
- Android之BroadcastReceiver讲义并通过广播机制实现短信窃听
- android HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理(2)
- Android开发(24)---安卓中实现多线程下载(带进度条和百分比)
- Android平台下实现音视频通信的应用开发
- android 开发之socket编程 UDP和TCP通信实现
- Android通过AIDL实现下载进程通信
- Android基于XMPP Smack Openfire开发IM【四】初步实现两个客户端通信
- android开发步步为营之1:Handler让主线程和子线程进行通信
- 在通过android的广播机制拦截短信的实现过程中遇到的问题
- 实现在Android本地视频播放器开发