Android 无法在未调用looper prepare的线程内创建处理程序
我是新手安卓程序员。刚开始看一些在线教程,我决定为自己申请。。直到昨天,天气一直很好。。我今天所做的唯一更改就是添加了这一行this.requestWindowFeatureWindow.FEATURE\u NO\u TITLE;它指出了错误。请提供解决方案Android 无法在未调用looper prepare的线程内创建处理程序,android,loops,handler,Android,Loops,Handler,我是新手安卓程序员。刚开始看一些在线教程,我决定为自己申请。。直到昨天,天气一直很好。。我今天所做的唯一更改就是添加了这一行this.requestWindowFeatureWindow.FEATURE\u NO\u TITLE;它指出了错误。请提供解决方案 public class MainActivity extends Activity implements OnClickListener, Runnable { Context context; EditText editTextNum
public class MainActivity extends Activity implements OnClickListener, Runnable {
Context context;
EditText editTextNum, editText, editUserName, editPassword;
Button btnsend;
ProgressDialog pd;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
editUserName = (EditText) findViewById(R.id.edit_userName);
editPassword = (EditText) findViewById(R.id.edit_password);
editTextNum = (EditText) findViewById(R.id.edit_number);
editText = (EditText) findViewById(R.id.edit_message);
btnsend = (Button) findViewById(R.id.btnsend);
btnsend.setOnClickListener(this);
}
/** Called when the user clicks the Send button */
public void sendMessage() {
if (!isOnline()) {
Toast.makeText(MainActivity.this,"No Internet Access..Cannot Send SMS", Toast.LENGTH_LONG).show();
} else {
String userName = editUserName.getText().toString();
String password = editPassword.getText().toString();
String number = editTextNum.getText().toString();
String message = editText.getText().toString();
String msgreciever = number;
String testMessage = message;
try {
SmsSender.sendMessage(msgreciever, testMessage, userName, password);
} catch (Exception ex) {
Toast.makeText(MainActivity.this, "SMS Sending Failed.",Toast.LENGTH_LONG).show();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
public void onClick(View v) {
// TODO Auto-generated method stub
if (v == btnsend) {
if (!isOnline()) {
Toast.makeText(MainActivity.this,"No Internet Access..Cannot Send SMS",Toast.LENGTH_LONG).show();
} else {
pd = ProgressDialog.show(MainActivity.this, "Free Sms","Sending SMS..Please Wait..!!", true);
Thread t = new Thread(this);
t.start();
}
}
}
public void run() {
// TODO Auto-generated method stub
sendMessage();
mHandler.sendEmptyMessage(0);
}
public Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
pd.dismiss();
Toast.makeText(MainActivity.this, "Message Sent Successfully",Toast.LENGTH_LONG).show();
editTextNum.setText("");
editText.setText("");
editTextNum.requestFocus();
}
};
}
查看我的帖子,它解释了这背后的原因:简言之,您需要为处理程序提供来自某个线程的循环器。您始终可以通过执行new HandlerLooper.getMainLooper来实现此目的: 此外,您不应该在活动中管理自己的线程,或者至少不应该经常这样做。您需要做的是如我所示创建处理程序,然后调用mHandler.postrunnable,传入您想要运行的runnable。您正在不必要地创建一个新线程,以便可以对其调用start,从而执行Runnable的run方法。为什么不让处理程序直接运行它呢 所以它应该看起来像:
Handler mHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
public void run() {work here...}
}
...elsewhere
mHandler.post(myRunnable);
事实上,如果你这样做的话,如果没有使用Looper.getMainLooper它也不能工作,我会感到惊讶
编辑
我不知道SmsSender是什么,但这很可能是导致您尝试新线程的原因。如果SmsSender正在做一些长时间运行的工作,那么您应该做的是在后台使用AsyncTask来完成这些工作。然后在onPostExecute中,您可以使用相关的内容更新UI。您似乎试图自己实现AsyncTask的功能,尽管没有成功。明白为什么吗?您试图在后台执行一些昂贵的工作,然后使用处理程序让UI更新状态。这正是AsyncTask旨在帮助您完成的任务,只是它正确地实现了所有这一切,并使您更轻松 查看我的文章,其中解释了这背后的原因:简而言之,您需要为处理程序提供来自某个线程的循环器。您始终可以通过执行new HandlerLooper.getMainLooper来实现此目的: 此外,您不应该在活动中管理自己的线程,或者至少不应该经常这样做。您需要做的是如我所示创建处理程序,然后调用mHandler.postrunnable,传入您想要运行的runnable。您正在不必要地创建一个新线程,以便可以对其调用start,从而执行Runnable的run方法。为什么不让处理程序直接运行它呢 所以它应该看起来像:
Handler mHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
public void run() {work here...}
}
...elsewhere
mHandler.post(myRunnable);
事实上,如果你这样做的话,如果没有使用Looper.getMainLooper它也不能工作,我会感到惊讶
编辑
我不知道SmsSender是什么,但这很可能是导致您尝试新线程的原因。如果SmsSender正在做一些长时间运行的工作,那么您应该做的是在后台使用AsyncTask来完成这些工作。然后在onPostExecute中,您可以使用相关的内容更新UI。您似乎试图自己实现AsyncTask的功能,尽管没有成功。明白为什么吗?您试图在后台执行一些昂贵的工作,然后使用处理程序让UI更新状态。这正是AsyncTask旨在帮助您完成的任务,只是它正确地实现了所有这一切,并使您更轻松 这对我有用,但我使用的是ProgressDialog
myProgressDialog = ProgressDialog.show(MyActivity.this,
getString(R.string.texto1) + "...",
getString(R.string.texto2) + "...", true);
myProgressDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
new Thread( new Runnable() {
public void run() {
runOnUiThread(new Runnable(){
public void run() {
Toast t = Toast.makeText(getApplicationContext(), "cadena a mostrar", Toast.LENGTH_SHORT);
t.show();
}
});
myProgressDialog.dismiss();
}
}).start();
这对我有用,但我使用的是ProgressDialog
myProgressDialog = ProgressDialog.show(MyActivity.this,
getString(R.string.texto1) + "...",
getString(R.string.texto2) + "...", true);
myProgressDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
new Thread( new Runnable() {
public void run() {
runOnUiThread(new Runnable(){
public void run() {
Toast t = Toast.makeText(getApplicationContext(), "cadena a mostrar", Toast.LENGTH_SHORT);
t.show();
}
});
myProgressDialog.dismiss();
}
}).start();
但是当我没有创建一个新线程时,当我点击send按钮时,应用程序在执行发送消息的代码时被冻结了,所以看起来应用程序已经挂起了。创建新线程后,该问题得到解决。你也可以编辑我的代码并提供解决方案。SmsSender是一个类,它实现了通过网站www.way2sms.com发送短信的功能&而且我不知道如何在我的应用程序中实现异步。@TapanDesai,开发文档是你的朋友:你能看看我的整个项目吗?但是当我没有创建一个新的线程时,当我点击发送按钮时,应用程序在执行发送消息的代码时被冻结了,所以看起来应用程序已经挂起了。创建新线程后,该问题得到解决。你也可以编辑我的代码并提供解决方案。SmsSender是一个类,它实现了通过网站www.way2sms.com发送短信的功能&而且我不知道如何在我的应用程序中实现异步。@TapanDesai,开发文档是你的朋友:你能看看我的整个项目吗?