我正在建立一个关于学校的独立时间表应用程序。我现在处于我的应用程序的测试阶段,它在Android版本2.3.6上工作正常
然而,当我尝试在虚拟设备上运行时,它会像平常一样启动。
但是,在点击应执行登录过程的按钮后,应用程序将返回以下错误:
01-05 00:52:23.180: E/AndroidRuntime(858): FATAL EXCEPTION: main
01-05 00:52:23.180: E/AndroidRuntime(858): java.lang.IllegalStateException: Could not execute method of the activity
01-05 00:52:23.180: E/AndroidRuntime(858): at android.view.View$1.onClick(View.java:3597)
01-05 00:52:23.180: E/AndroidRuntime(858): at android.view.View.performClick(View.java:4202)
01-05 00:52:23.180: E/AndroidRuntime(858): at android.view.View$PerformClick.run(View.java:17340)
01-05 00:52:23.180: E/AndroidRuntime(858): at android.os.Handler.handleCallback(Handler.java:725)
01-05 00:52:23.180: E/AndroidRuntime(858): at android.os.Handler.dispatchMessage(Handler.java:92)
01-05 00:52:23.180: E/AndroidRuntime(858): at android.os.Looper.loop(Looper.java:137)
01-05 00:52:23.180: E/AndroidRuntime(858): at android.app.ActivityThread.main(ActivityThread.java:5039)
01-05 00:52:23.180: E/AndroidRuntime(858): at java.lang.reflect.Method.invokeNative(Native Method)
01-05 00:52:23.180: E/AndroidRuntime(858): at java.lang.reflect.Method.invoke(Method.java:511)
01-05 00:52:23.180: E/AndroidRuntime(858): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-05 00:52:23.180: E/AndroidRuntime(858): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-05 00:52:23.180: E/AndroidRuntime(858): at dalvik.system.NativeStart.main(Native Method)
01-05 00:52:23.180: E/AndroidRuntime(858): Caused by: java.lang.reflect.InvocationTargetException
01-05 00:52:23.180: E/AndroidRuntime(858): at java.lang.reflect.Method.invokeNative(Native Method)
01-05 00:52:23.180: E/AndroidRuntime(858): at java.lang.reflect.Method.invoke(Method.java:511)
01-05 00:52:23.180: E/AndroidRuntime(858): at android.view.View$1.onClick(View.java:3592)
01-05 00:52:23.180: E/AndroidRuntime(858): ... 11 more
01-05 00:52:23.180: E/AndroidRuntime(858): Caused by: android.os.NetworkOnMainThreadException
01-05 00:52:23.180: E/AndroidRuntime(858): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
01-05 00:52:23.180: E/AndroidRuntime(858): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
01-05 00:52:23.180: E/AndroidRuntime(858): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
01-05 00:52:23.180: E/AndroidRuntime(858): at java.net.InetAddress.getAllByName(InetAddress.java:214)
01-05 00:52:23.180: E/AndroidRuntime(858): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
01-05 00:52:23.180: E/AndroidRuntime(858): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-05 00:52:23.180: E/AndroidRuntime(858): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-05 00:52:23.180: E/AndroidRuntime(858): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-05 00:52:23.180: E/AndroidRuntime(858): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
01-05 00:52:23.180: E/AndroidRuntime(858): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
01-05 00:52:23.180: E/AndroidRuntime(858): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
01-05 00:52:23.180: E/AndroidRuntime(858): at com.mattle.timetable.JSONParser.getJSONFromUrl(JSONParser.java:42)
01-05 00:52:23.180: E/AndroidRuntime(858): at com.mattle.timetable.LoginView.doLogin(LoginView.java:129)
01-05 00:52:23.180: E/AndroidRuntime(858): ... 14 more
我使用此页面中的jsonparser类:http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
我的登录代码如下:
package com.mattle.timetable;
import static com.mattle.timetable.MainActivity.PREFS_NAME;
import java.io.BufferedReader;
import java.math.BigInteger;
import java.net.URI;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import com.google.android.gcm.GCMRegistrar;
import com.markupartist.android.widget.ActionBar;
public class LoginView extends Activity {
private JSONParser jsonParser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_view);
ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar);
// You can also assign the title programmatically by passing a
// CharSequence or resource id.
actionBar.setTitle("Jouw Lesrooster");
}
@Override
public void onBackPressed() {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}
private String getStringResourceByName(String aString)
{
String packageName = "com.mattle.timetable";
int resId = getResources().getIdentifier(aString, "string", packageName);
return getString(resId);
}
private boolean haveNetworkConnection() {
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
haveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
return haveConnectedWifi || haveConnectedMobile;
}
public String sha1(String s) {
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
digest.reset();
byte[] data = digest.digest(s.getBytes());
return String.format("%0" + (data.length*2) + "X", new BigInteger(1, data));
}
public void doRegister(View view) {
Intent gotoregister = new Intent(this, Register.class);
startActivity(gotoregister);
}
public void doLogin(View view) throws Exception {
BufferedReader in = null;
try{
if(haveNetworkConnection()) {
EditText getusername = (EditText) findViewById(R.id.username);
String username = getusername.getText().toString();
EditText getpassword = (EditText) findViewById(R.id.password);
String password = sha1(getpassword.getText().toString() + "SOMESALTHERENVM");
HttpClient client = new DefaultHttpClient();
URI website = new URI("SOMEURL");
HttpPost request = new HttpPost();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("login_username", username));
nameValuePairs.add(new BasicNameValuePair("login_password", password));
jsonParser = new JSONParser();
JSONObject json = jsonParser.getJSONFromUrl("http://jouwlesrooster.nl/api/doLogin/", nameValuePairs);
try {
if (json.getString("success") != null) {
String res = json.getString("success");
if(Integer.parseInt(res) == 1){
//Log.d("MYTAG", "Print this in logcat...");
//Log.d("MYTAG", username + " ddd " + password);
getSharedPreferences("myLoginshit",MODE_PRIVATE)
.edit()
.putString("Username", username)
.putString("Password", password)
.commit();
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, "***");
Log.i("test", "ddd");
// Toast.makeText(getApplicationContext(), "", Toast.LENGTH_LONG).show();
} else {
// Toast.makeText(getApplicationContext(), "Already registered", Toast.LENGTH_LONG).show();
// Log.v(TAG, "Already registered");
}
Intent gotomenu = new Intent(this, Menu.class);
startActivity(gotomenu);
}
}
} finally {
}
} else {
}
}finally{
if (in != null) {
try{
in.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
如何解决这个恼人的错误?
由于 Mattle酒店
答案 0 :(得分:1)
问题是doLogin()
- 方法,它在UI线程上执行网络任务。
查看StackTrace,您可以看到:
Caused by: android.os.NetworkOnMainThreadException
自Android“冰淇淋三明治”以来,它就被抛出了。要摆脱它,请将网络代码放在AsyncTask
。中
答案 1 :(得分:1)
看起来您正在从UI-Thread执行doLogin()
方法(可能在按钮中有一些onClick
方法)。
您不应该这样做,因为网络访问可能很慢并且可能会冻结UI。请改用AsyncTask类(参见http://developer.android.com/reference/android/os/AsyncTask.html)
答案 2 :(得分:1)