新建thread耗时,主线程依然卡死

移动开发 码拜 8年前 (2016-05-30) 1953次浏览
最近在学多线程任务处理,在以前的一个demo中用了一下,结果在new thread中耗时,主线程依然卡住。求高手指点。

package com.calendar.weather;
import java.util.List;
import com.example.liujiangcalendar.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.Toast;
public class WeatherActivity extends Activity {
// 分别显示近三天的天气信息和城市介绍

	private Spinner city, citys;
	private List<String> weater;
	private TextView cityNames1, cityNames2, cityNames3, cityjie;
	private ImageView weateImage1, weateImage2, weateImage3;
	private final int SUCCESS = 1;
	private final int FAIL = 0;
	private final int GET_CITYS = 0;
	private final int GET_CITY = 1;
	private final int GET_WEATHER = 2;
	private weThread wth;
	public Handler mHandler;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_weather);
		citys = (Spinner) findViewById(R.id.citys);
		citys.setAdapter(null);
		city = (Spinner) findViewById(R.id.city);
		city.setAdapter(null);
		cityNames1 = (TextView) findViewById(R.id.cityNames1);
		cityNames2 = (TextView) findViewById(R.id.cityNames2);
		cityNames3 = (TextView) findViewById(R.id.cityNames3);
		cityjie = (TextView) findViewById(R.id.cityjie);
		weateImage1 = (ImageView) findViewById(R.id.weateImage1);
		weateImage2 = (ImageView) findViewById(R.id.weateImage2);
		weateImage3 = (ImageView) findViewById(R.id.weateImage3);

		mHandler = new Handler(){

			public void handleMessage(Message msg){
				if (msg.arg1 == SUCCESS){
					switch(msg.what){
					case GET_CITYS:
						citys.setAdapter((SpinnerAdapter) msg.obj);
						break;
					case GET_CITY:
						city.setAdapter((SpinnerAdapter) msg.obj);
						break;
					case GET_WEATHER:
						weater = (List<String>) msg.obj;
						cityNames1.setText(weater.get(6) + "\n" + weater.get(5) + "\n"
								+ weater.get(7));
						//cityNames1.setBackgroundResource(Image.imageId(weater.get(8)));
						weateImage1.setImageResource(Image.imageId(weater
								.get(8)));
						cityNames2.setText(weater.get(13) + "\n" + weater.get(12) + "\n"
								+ weater.get(14));
						//cityNames2.setBackgroundResource(Image.imageId(weater.get(15)));
						weateImage2.setImageResource(Image.imageId(weater
								.get(15)));
						cityNames3.setText(weater.get(18) + "\n" + weater.get(17) + "\n"
								+ weater.get(19));
						//cityNames3.setBackgroundResource(Image.imageId(weater.get(20)));
						weateImage3.setImageResource(Image.imageId(weater
								.get(21)));
						cityjie.setText(weater.get(22));
						break;
					}
				}else{
					Toast.makeText(WeatherActivity.this, "无法获取信息,请检查网络设置之后重试", Toast.LENGTH_SHORT).show();
					//WeatherActivity.this.finish();
				}
			}
		};


		citys.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				Message msg = new Message();
				msg.what = GET_CITY;
				Bundle b = new Bundle();
				b.putString("citys", citys.getSelectedItem().toString());
				msg.setData(b);
				wth.thHandler.sendMessage(msg);
			}
			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub

			}
		});

		city.setOnItemSelectedListener(new OnItemSelectedListener() {
			// 返回数据: 一个一维数组 String(22),共有23个元素。
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {

				Message msg = new Message();
				msg.what = GET_WEATHER;
				Bundle b = new Bundle();
				b.putString("citys", city.getSelectedItem().toString());
				msg.setData(b);
				wth.thHandler.sendMessage(msg);


			}
			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub

			}

		});
	}

	@Override
	public void onStart(){
		super.onStart();
		wth = new weThread();
		Message msg01 = new Message();
		msg01.what = GET_CITYS;
		wth.thHandler.sendMessage(msg01);
		wth.start();
	}

	class weThread extends Thread{
		private List<String> list;
		public Handler 	thHandler = new Handler(){
			public void handleMessage(Message msg){

				Message m = new Message();
				m.what = msg.what;
				ArrayAdapter<String> mAdater = null;
				if(msg.what == GET_WEATHER){
					try{
						list = WeatherInfo.getWeather(msg.getData().getString("citys"));
						if (list != null && !list.isEmpty())
							m.arg1 = SUCCESS;
						else
							m.arg1 = FAIL;
					}catch(Exception e){
						m.arg1 = FAIL;
					}finally{
						m.obj = list;
						Log.i("*******", "send message arg1 ="+m.arg1);
						WeatherActivity.this.mHandler.sendMessage(m);
					}
				}else{
					try {
						if(msg.what == GET_CITY)
							list = WeatherInfo.getCity(msg.getData().getString("citys"));
						else
							list = WeatherInfo.getCitys();

						mAdater = new ArrayAdapter<String>(WeatherActivity.this,
								android.R.layout.simple_list_item_multiple_choice, list);

						if(mAdater != null && !mAdater.isEmpty())
							m.arg1 = SUCCESS;
						else
							m.arg1 = FAIL;
					} catch (Exception e) {
						m.arg1 = FAIL;
					}

					m.obj = mAdater;
					Log.i("*******", "send message arg1 ="+m.arg1);
					WeatherActivity.this.mHandler.sendMessage(m);
				}

			}
		};

		@Override
		public void run(){
			Looper.prepare();
			Looper.loop();
		}
	}
}
解决方案

10

你这哪里是用子线程了啊。用的还是主线程。Handle的处理是在主线程。你要把Handle处理放到run()中。而不是把handle定义在子线程的类里。

10

假如不是很复杂的线程操作 完全可以这样写

Thread myThread = new Thread(new Runnable() {
            @Override
            public void run() {
                //这里做耗时操做
                //......
                //......
                //做完以后
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //回主线程
                    }
                });
            }
        });
        myThread.start();

10

可以试试用AsyncTask,一般网络耗时操作本人都是用这个的
http://blog.csdn.net/anroidfinalbreak/article/details/38338107

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明新建thread耗时,主线程依然卡死
喜欢 (0)
[1034331897@qq.com]
分享 (0)