无法在Android中我的应用程序(第一页)的登录页中实现json解析

无法在Android中我的应用程序(第一页)的登录页中实现json解析,android,json,Android,Json,我是Android编程新手。我已经浏览了谷歌的大部分Android开发者文档。我的问题是: 我尝试做的是:从我应用程序的第一个登录页面,我尝试获取位于服务器中的json文件,并解析结果以检查登录是否成功。 我无法在下面的类中解析json。请提出问题所在。我已经检查了过去几天关于stackoverflow的所有其他问题,但没有多少帮助。请帮忙 LoginActivity.java package com.practice.serverdashboard; import java.io.Buf

我是Android编程新手。我已经浏览了谷歌的大部分Android开发者文档。我的问题是:

我尝试做的是:从我应用程序的第一个登录页面,我尝试获取位于服务器中的json文件,并解析结果以检查登录是否成功。 我无法在下面的类中解析json。请提出问题所在。我已经检查了过去几天关于stackoverflow的所有其他问题,但没有多少帮助。请帮忙

LoginActivity.java

package com.practice.serverdashboard;



import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.Service;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;

public class LoginActivity extends Activity {

    public EditText username;
    private EditText password;

    private static final String TAG = "MyActivity";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        username = (EditText) findViewById(R.id.txt_username);   
        password = (EditText) findViewById(R.id.txt_password);   

        //Showing the keypad
         InputMethodManager mgr = (InputMethodManager)this.getSystemService(Service.INPUT_METHOD_SERVICE);
         mgr.showSoftInput(username, InputMethodManager.SHOW_IMPLICIT);     
    }

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


    public void callLoginService(View v)
    {
        //Hidding the keypad
        InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        mgr.hideSoftInputFromWindow(username.getWindowToken(), 0);
        mgr.hideSoftInputFromWindow(password.getWindowToken(), 0);


        String loginUrlString="http://freakageekinternaltest.com:2200/mgmt/JSP/login.jsp?userId="+username.getText()+"&pws="+password.getText();
        Log.e("log_tag", "The URL is :: "+loginUrlString);
        //calling the login URL
        //GetJson gJ=new GetJson();
        //gJ.execute(loginUrlString);
        JSONObject json=getJSONfromURL(loginUrlString);


        AlertDialog.Builder adb = new AlertDialog.Builder(
                LoginActivity.this);
                adb.setTitle("Login Service");
                adb.setMessage("Testing...");
                adb.setPositiveButton("Ok", null);
                adb.show(); 


    }



public JSONObject getJSONfromURL(String url){

    //initialize
    InputStream is = null;
    String result = "";
    JSONObject jArray = null;

    //http post
    try{
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(url);
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        is = entity.getContent();

    }catch(Exception e){
        Log.e("log_tag", "Error in http connection "+e.toString());
    }

    //convert response to string
    try{
        BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        result=sb.toString();

        Log.e("log_tag", "result is:: "+result);

    }catch(Exception e){
        Log.e("log_tag", "Error converting result "+e.toString());
    }

    //try parse the string to a JSON object
    try{
            jArray = new JSONObject(result);
    }catch(JSONException e){
        Log.e("log_tag", "Error parsing data "+e.toString());
    }

    AlertDialog.Builder adb = new AlertDialog.Builder(
            LoginActivity.this);
            adb.setTitle("Login Service");
            adb.setMessage("Success...");
            adb.setPositiveButton("Ok", null);
            adb.show(); 

    return jArray;
}

}
以下是logcat输出:

02-13 11:13:15.173: E/log_tag(6083): The URL is :: http://freakageekinternaltest.com:2200/mgmt/JSP/login.jsp?userId=test567&pws=test@pps
02-13 11:13:15.183: E/log_tag(6083): Error in http connection android.os.NetworkOnMainThreadException
02-13 11:13:15.183: E/log_tag(6083): Error converting result java.lang.NullPointerException: lock == null
02-13 11:13:15.183: E/log_tag(6083): Error parsing data org.json.JSONException: End of input at character 0 of 
由于NetworkOnMainThreadException异常(在stackoverflow的帮助下),我也签出了AsyncTask。但我不知道从哪里开始,也不知道如何在我的LoginActivity.java类中使用Async类。请帮忙。先谢谢你

以下是我试图从服务器获取并解析的json:

{"LOGIN":"TRUE","userId":"Web Administrator","userAccessType":"ALL"}
@加贝:谢谢你方早日回复加贝。是否必须在后台进行联网操作?由于我正在尝试从服务器获取登录详细信息,当我的应用程序只是坐在那里等待服务器响应时,它会做什么?另外,考虑到我上面的代码,如何实现AsyncTask类?我已经看过了你提到的文件。但我尝试创建一个扩展AsyncTask的新类。在那个类中,我用doInBackground方法完成了所有的网络操作,thn使用onPostExecute方法将结果发送回LoginActivity.java类。但是,由于此后台操作是在扩展AsyncTask类的新类上完成的,因此我无法使用在我的main_activity.xml文件中定义的控件。那么如何实现这一切呢?又是Thx

你好! 现在我已经按照答案中的建议修改了代码

private class RetreiveDataAsynctask extends AsyncTask<String,Void,JSONObject> {

        @Override
        protected JSONObject doInBackground(String... loginURL) {
            JSONObject obj = getJSONfromURL(loginURL);
            return obj;
        }

        @Override
        protected void onPostExecute(JSONObject obj) {
             //Do all ur UI related stuff as this will be executing in ui thread

            super.onPostExecute(obj);
        }


    }
但是,它在这一行中给出了错误:

JSONObject obj = getJSONfromURL(loginURL);
谁能告诉我这个代码有什么问题吗?其余的解析函数与上面指定的相同。 提前发送Thx。

错误

Error in http connection android.os.NetworkOnMainThreadException
表示您正在主线程上执行工作,但应在单独的线程中执行,因为网络操作会阻塞用户界面

您可以使用
AsyncTask
执行网络操作

有关更多信息,请参阅

看看这个
有关详细信息。

将异步任务设置为:

private class RetreiveDataAsynctask extends AsyncTask<String loginUrlString, Void, JSONObject> {

    @Override
    protected Response doInBackground(Void... params) {
        JSONObject obj = getJSONfromURL( loginUrlString);
        return obj;
    }

    @Override
    protected void onPostExecute(JSONObject obj) {
         //Do all ur UI related stuff as this will be executing in ui thread

        super.onPostExecute(result);
    }


}
试试这个:

class Communicator extends AsyncTask<String, String, String> 
    {
        @Override
        protected String doInBackground(String... params) {
            //Here call the method for parsing
        }

        @Override
        protected void onPreExecute() 
        {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String result) 
        {
            super.onPostExecute(result);
        }
    }

//And on callLoginService(View v) you start the AsyncTask
        //if you want to pass some value
        String values[] = { userna, passwo };
        new Communicator().execute(values); 
        //Otherwise
        new Communicator().execute(); 
类通信器扩展异步任务 { @凌驾 受保护的字符串doInBackground(字符串…参数){ //这里调用用于解析的方法 } @凌驾 受保护的void onPreExecute() { super.onPreExecute(); } @凌驾 受保护的void onPostExecute(字符串结果) { super.onPostExecute(结果); } } //在callLoginService(视图v)上启动异步任务 //如果你想传递一些值 字符串值[]={userna,passwo}; 新建通信器()。执行(值); //否则 新建通信器().execute();
使用异步任务从url获取Json。。 或者在方法中添加以下两行

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); 

参考这篇文章,它可能会对你有所帮助。这只是一个系统库,不是法官法庭。如果你尝试在主线程上建立网络,它会抛出一个异常,不管你是有最好的理由这样做,还是最坏的理由,没有律师可以帮助你。@Audrius Meškauskas:这意味着我们只需要遵循这条规则,但它不是强制性的?如果我们有一些要求,我们可以跳过这条规则(╯°□°)╯︵ ┻━┻ 这是一个非常糟糕的建议。如果你必须发布它,至少解释一下它为什么不好,以及如何做得对。tx供你回复。请检查我的编辑,看看有什么问题。我确实用一个异步任务示例编辑了我的答案。我不会发布代码,我只是给出提示。将长任务卸载到后台的概念对于理解(android)programming.thx中的示例至关重要。我只是检查一下。如果有帮助,我会选择这个作为正确答案。再次谢谢。谢谢你的回复。在哪里写这个文件?在LoginActivity.java文件本身中,还是需要创建一个名为RetreiveDataAsynctask.java的单独文件?由于RetreiveDataAsynctask与我的LoginActivity.java是一个不同的类,因此我是否能够从这个类访问与UI相关的内容?在ur LoginActivity.java文件中定义这个类RetreiveDataAsynctask.and在ur LoginActivity.java的OnCreate中定义这个mRetreiveData.execute();是的,我是按照你的建议做的。在LoginActivity.java中,我有:RetreiveDataAsynctask mRetreiveData=new RetreiveDataAsynctask();mRetreiveData.execute(loginUrlString);=>这将返回一个json对象。对吗?因此,如果我想存储这个json对象以进行解析/其他操作,我会这样写:JSONObject json=mRetreiveData.execute(loginUrlString);=>为什么这是一个错误?等待你的答复。好的,我来试试这个。你能告诉我AsyncTask中的这些参数是什么吗?你为什么用绳子?为什么不是void、Long或int?我在很多地方看到人们在不同的场景中使用不同的东西。我们到底要找什么?好的,要弄清楚参数,请检查此链接
class Communicator extends AsyncTask<String, String, String> 
    {
        @Override
        protected String doInBackground(String... params) {
            //Here call the method for parsing
        }

        @Override
        protected void onPreExecute() 
        {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String result) 
        {
            super.onPostExecute(result);
        }
    }

//And on callLoginService(View v) you start the AsyncTask
        //if you want to pass some value
        String values[] = { userna, passwo };
        new Communicator().execute(values); 
        //Otherwise
        new Communicator().execute(); 
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);