异步造成的参数传不进去

这是困扰我很久的一个问题。现在做一下总结。
出于性能优化角度考虑,Android UI操作并不是线程安全的,意味着如果有多个线程并发操作UI组件可能导致线程安全问题。因而,只允许UI线程修改Activity里的UI组件。当程序第一次启动时,Android会同时启动一条Main Thread(主线程),Main Thread主要负责处理与UI相关的事件,比如按键触屏及屏幕绘图,并将相关事件分发到对应的组件进行处理。因此Main Thread称为UI线程。
Android 的消息传递机制是另一种形式的“事件处理”,这种传递机制主要为了解决Android 应用多线程的问题——新启动的线程无法动态改变界面组件的属性值。实际开发中,需让新启动的线程周期性改变界面组件的属性值,需要借助Handle消息传递机制来实现。
————————————————————————————

Handle,作用有二:在新启动的线程里发送消息;在主线程中获取处理消息。为了使主线程能适时处理新线程所发动的消息,显然只能通过回调的方式——重写Handle类中处理消息的办法,当启动新线程发送消息时,消息会发生到与之关联的MessageQuene,Handle会不断从MessageQueue获取并处理消息——这将导致Handle类中处理消息方法回调。

Message:Handle接受处理的消息;
Looper:每个线程只有一个。它的loop方法负责读取 MessageQueue中的消息,读到后将消息给Handle处理;
MessageQueue:消息队列,采用先进先出得方式管理Message。程序创建Looper对象时会在其构造器中创建MessageQueue对象。

在线程中调用Handle步骤:调用Looper的prepare(),为当前线程创建Looper对象,构造器与此同时创建配套MessageQueue;创建Handle子类实例,重写handleMessage();调用Looper的loop方法启动。

package ustb.sk.iotintelligence.activity;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;

import org.json.JSONException;
import org.json.JSONObject;

import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import ustb.sk.iotintelligence.R;
import ustb.sk.iotintelligence.speech.util.JsonParser;

public class ChatTogether extends Activity {//回答没有显示在listview中
    private Button btChat;
    private ListView lvChat;
    String TAG = ChatTogether.class.getSimpleName();
    private RequestQueue mRequestQueue;
    private String baseUrl="http://apis.baidu.com/turing/turing/turing";
    private HashMap<String,String> mIatResults = new LinkedHashMap<String, String>();// 用HashMap存储说话人听写结果
    List<Map<String,String>> lists = new ArrayList<Map<String, String>>();//创建一个List集合,集合元素是Map
    Map<String,String> list = new HashMap<String, String>();//list由time与detail组成
    final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年mm月dd日HH:mm:ss");
    Date date = new Date(System.currentTimeMillis());//时间
    final Handler handler=new Handler()
    {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0x123:
                    Log.v("vvvvv", "0123");
                    String input  = msg.obj.toString();//将说话内容放入参数中

                    Log.v("vvvvv","45");
                    String requestUrl = baseUrl + "?key=879a6cb3afb84dbf4fc84a1df2ab7319&info=" + URLEncoder.encode(input) + "&userid=eb2edb736";
      //              Log.v("test", "request url is" + requestUrl);
                   //     String requestUrl="key=879a6cb3afb84dbf4fc84a1df2ab7319&info=%E6%9F%A5%E5%A4%A9%E6%B0%94%E2%80%9C%E5%8C%97%E4%BA%AC%E4%BB%8A%E5%A4%A9%E5%A4%A9%E6%B0%94%E2%80%9D&userid=eb2edb736";
                    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, requestUrl, null, new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject jsonObject) {
                            try {
                                Log.v("test", "get response success");
                                Log.v("test", "response is" + jsonObject.get("text").toString());

                                list.put("time", simpleDateFormat.format(date));
                                list.put("detail", jsonObject.get("text").toString());
                                lists.add(list);
                                Log.v("timewhat2",list.get("time"));
                                Log.v("detailwhat2", list.get("detail"));


                            } catch (Exception exception) {
                                Log.v("test", "json exception" + exception.toString());
                            }
                        }
                    }, new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError volleyError) {
                            Log.v("test", "get response fail");
                        }
                    }) {
                        @Override
                        public Map<String, String> getHeaders() {
                            HashMap<String, String> headers = new HashMap<String, String>();
                            headers.put("apikey", "37d6b6cc3972f5392e35cf9e391b8b5e");//37d6b6cc3972f5392e35cf9e391b8b5e
                            return headers;
                        }

                    };
                    mRequestQueue.add(jsonObjectRequest);
                    SimpleAdapter simpleAdapter = new SimpleAdapter(ChatTogether.this,lists,R.layout.notelist_item,new String[] { "time" , "detail" },new int[] {R.id.time, R.id.detail} );
                    ListView listView = (ListView)findViewById(R.id.lvChat);
                    listView.setAdapter(simpleAdapter);
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SpeechUtility.createUtility(getApplicationContext(), SpeechConstant.APPID + "=55b20041");
        setContentView(R.layout.activity_chat_together);
        mRequestQueue = Volley.newRequestQueue(getApplication());
        btChat = (Button) findViewById(R.id.btChat);
        btChat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {//点击说话
                RecognizerDialog recognizerDialog = new RecognizerDialog(ChatTogether.this, null);//创建对象,本地听写的话第二个参数传InitListener
                recognizerDialog.setParameter(SpeechConstant.DOMAIN, "iat");//设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
                recognizerDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
                recognizerDialog.setParameter(SpeechConstant.ACCENT, "mandarin ");
                recognizerDialog.setListener(recognizerDialogListener);//开始听写
                recognizerDialog.show();//asset下的动画
                Log.v("test", "click button");
            }
        });
    }

    public RecognizerDialogListener recognizerDialogListener = new RecognizerDialogListener() {//听写监听器
        @Override
        public void onResult(RecognizerResult recognizerResult, boolean isLast) {
       /* 听写结果回调接口(返回Json格式结果,用户可参见附录12.1);
         一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;
         关于解析Json的代码可参见MscDemo中JsonParser类;
        isLast等于true时会话结束。*/
            Log.v("jsonresult", recognizerResult.getResultString());
            Log.v("this is dialog result", JsonParser.parseIatResult(recognizerResult.getResultString()));
            Message  msg=new Message();
            msg.what=0x123;
            msg.obj=jsonChange(recognizerResult);
            handler.sendMessage(msg);
            list.put("time", simpleDateFormat.format(date));
            list.put("detail", msg.obj.toString());
            Log.v("timewhat1", list.get("time"));
            Log.v("detailwhat1", list.get("detail"));
        }
        @Override
        public void onError(SpeechError speechError) {
            Log.v(TAG,"this is error");
            Log.v(TAG, speechError.toString());
        }
    };

    public  String jsonChange(RecognizerResult results) {//将json转换为汉字--我还不太懂
        String text = JsonParser.parseIatResult(results.getResultString());
        String sn = null;

        // 读取json结果中的sn字段
        try {
            JSONObject resultJson = new JSONObject(results.getResultString());
            sn = resultJson.optString("sn");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        mIatResults.put(sn, text);
        StringBuffer resultBuffer = new StringBuffer();
        for (String key : mIatResults.keySet()) {
            resultBuffer.append(mIatResults.get(key));
        }
        Log.v("finalresult", resultBuffer.toString());
        return resultBuffer.toString();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_chat_together, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
### Thymeleaf 数据无法加载的原因分析 Thymeleaf的数据渲染延迟可能导致数据未能及时显示。具体来说,在页面跳转过程中,如果用户过早地交互(如点击超链接),而此时Thymeleaf尚未完成数据渲染,则可能会遇到预期之外的行为[^2]。 为了缓解这一现象,可以考虑调整Thymeleaf的配置参数或者优化前端代码结构来减少这种延迟的影响。例如: - **禁用缓存**:在开发环境中关闭Thymeleaf模板缓存能够有效防止因缓存引起的旧版本模板被使用的情况发生。 ```properties spring.thymeleaf.cache=false ``` - **异步处理**:对于耗时较长的操作,建议采用AJAX或其他形式的异步调用来获取动态内容,从而影响整体页面性能。 - **预加载资源**:确保必要的JavaScript和CSS文件提前加载完毕,避免因为这些外部依赖项未准备好而导致的功能失效问题[^5]。 另外,关于静态资源管理方面,可以通过设置合理的HTTP头信息以及利用浏览器内置的缓存策略提高访问速度;同时也要注意审查是否存在必要的大型脚本拖慢了整个网页的表现效率。 最后值得注意的是,当结合前后端框架一起工作时(比如Spring Boot + Vue.js),应该合理分配各自职责范围内的任务,让两者协同合作而是互相干扰。例如,可以在服务端预先填充好初始状态下的DOM节点及其属性值,之后再交由客户端接管后续更新操作[^4]。 ### 技术细节补充说明 针对特定场景下可能出现的具体技术难题,这里给出一些额外指导: - 如果发现某些情况下即使等待较长时间也无法正常展示所需信息,可能是由于网络连接稳定或是服务器响应缓慢造成的。这时除了改善基础设施条件外,还可以尝试引入重试机制或提示消息告知访客当前状况并给予适当反馈。 - 对于较为复杂的业务逻辑表达式,应当尽量简化其复杂度,并且充分利用局部变量存储中间计算结果以提升执行效能。此外,保持良好的编码习惯也有助于排查潜在错误源。 #### 示例代码片段 下面是一个简单的例子展示了如何向模型中添加用于SEO的关键字描述字段: ```java @Controller public class SeoController { @GetMapping("/seo-page") public String seoPage(Model model) { // 向Model对象里加入标题、描述等内容供视图层读取 model.addAttribute("pageTitle", "网站名称 | 关键词"); model.addAttribute("metaDescription", "这里是有关此页目的简短介绍文字..."); return "templateName"; } } ``` 上述方法有助于增强基于搜索引擎抓取工具识别能力的同时也提高了用户体验质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值