0

去年我做了一个 android 应用程序,它运行良好,我被重新分配开发应用程序。

但是用户的注册已经停止工作。原因,我一点头绪都没有。

这是我的开始屏幕,用户注册的活动:

public class Prompt extends Activity {

    public EditText u, p, e;
    public String username, password, emailadd;
    public Button createClient;
    final Context context = this;
    public TextView registerErrorMsg;

    // JSON Response node names
    private static String KEY_SUCCESS = "success";
    @SuppressWarnings("unused")
    private static String KEY_ERROR = "error";
    @SuppressWarnings("unused")
    private static String KEY_ERROR_MSG = "error_msg";
    private static String KEY_UID = "uid";
    private static String KEY_NAME = "name";
    private static String KEY_EMAIL = "email";
    private static String KEY_CREATED_AT = "created_at";

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.prompt);
        // Importing all assets like buttons, text fields

        u = (EditText) findViewById(R.id.username);
        p = (EditText) findViewById(R.id.Password);
        e = (EditText) findViewById(R.id.emailAddress);
        createClient = (Button) findViewById(R.id.createClient);
        registerErrorMsg = (TextView) findViewById(R.id.register_error);
        u.setText("usernametest");
        p.setText("passwordtest");
        e.setText("TEST@gmail.com");

        //Toast.makeText(getApplicationContext(), "...", Toast.LENGTH_LONG).show();

        createClient.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                username = u.getText().toString();
                password = p.getText().toString();
                emailadd = e.getText().toString();
                UserFunctions userFunction = new UserFunctions();

                //Toast.makeText(getApplicationContext(), username+" "+password+" "+emailadd, Toast.LENGTH_LONG).show();

                //now we have text input, validate them
                if(username.length() < 5 || password.length() < 5 || emailadd.length() < 5){
                    //minimum input for each field is > 5 characters
                    registerErrorMsg.setText("Username, password and email must have must than 5 characters");
                }
                else{
                    //if validated correctly upload
                    JSONObject json = userFunction.registerUser(username, emailadd, password);
                    Log.e("JSON RESULT", "JSON result: " + json);

                    //successfully make the check file and redirect to the homepage
                    try {
                            String FILE_NAME = "filename.txt";
                            FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_WORLD_READABLE);
                            try{
                                fos.write(username.getBytes());
                            }catch (IOException e){
                                e.printStackTrace();
                            }
                            fos.close();

                            //if all complete, redirect to home page
                            Intent intent2 = new Intent(Prompt.this, StrategicEnergyActivity.class);
                            intent2.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(intent2);
                            finish();
                    } 
                    catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } 
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
}

这是我的 JSON Parser 类,用于处理从 Web 服务返回的 JSON:

public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    // constructor
    public JSONParser() {
    }

    public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {

        Log.e("TESTTTT", " " + params.get(0) + " " + params.get(1) + " " + params.get(2)  + " " + params.get(3));
        // Making HTTP request
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();
        } 
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } 
        catch (ClientProtocolException e) {
            e.printStackTrace();
        } 
        catch (IOException e) {
            e.printStackTrace();
        }

        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);
            }
            is.close();
            json = sb.toString();
            Log.e("JSON", json);
        } 
        catch (Exception e){
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

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

        // return JSON String
        return jObj;
    }
}

这是我的用户函数类,该类执行数据处理/方法调用:

public class UserFunctions {

    private JSONParser jsonParser;

    private static String registerURL = "http://www.website.com/api/index.php?";
    private static String register_tag = "register";

    // constructor
    public UserFunctions(){
        jsonParser = new JSONParser();
    }

    /**
     * function make Login Request
     * @param name
     * @param email
     * @param password
     * */
    public JSONObject registerUser(String name, String email, String password){
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("tag", register_tag));
        params.add(new BasicNameValuePair("name", name));
        params.add(new BasicNameValuePair("email", email));
        params.add(new BasicNameValuePair("password", password));

        Log.e("Credentials", "Username: " + name + "\nEmail: " + email + "\nPassword: " + password);
        //Toast.makeText(getParent(), name+" "+email+" "+password, Toast.LENGTH_LONG).show();

        JSONObject json = jsonParser.getJSONFromUrl(registerURL, params);
        return json;
    }
}

这是我的网络服务上的代码:

<?php
    print_r($_POST);
    $tag = "register";

    // include db handler
    require_once 'include/DB_Functions.php';
    $db = new DB_Functions();

    // response Array
    $response = array("tag" => $tag, "success" => 0, "error" => 0);

    // check for tag type
    if ($tag == 'register') {
        // Request type is Register new user
        $name = $_POST['name'];
        $email = $_POST['email'];
        $password = $_POST['password'];

        // check if user is already existed
        if($db->isUserExisted($email)){
            // user is already exists - error response
            $response["error"] = 2;
            $response["error_msg"] = "User Already Exists";
            echo json_encode($response). "User Already Exists";
        } 
        else{       
            // store user
            $user = $db->storeUser($name, $email, $password);

            if($user){
                // user stored successfully
                $response["success"] = 1;
                $response["uid"] = $user["unique_id"];
                $response["user"]["name"] = $user["name"];
                $response["user"]["email"] = $user["email"];
                $response["user"]["created_at"] = $user["created_at"];
                $response["user"]["updated_at"] = $user["updated_at"];
                echo json_encode($response). "User Stored Successfully";
            } 
            else{
                // user failed to store
                $response["error"] = 1;
                $response["error_msg"] = "Error occured in Registration";
                echo json_encode($response);
            }
        }
    } 
    else{
        echo "Invalid Request";
    }
?>

最后,这是当前向我抛出的错误,它发生在 JSONParser 类的 sb.append(line) 行中:

05-21 16:35:46.304: E/Buffer Error(4278): Error converting result java.lang.NullPointerException
05-21 16:35:46.308: E/JSON Parser(4278): Error parsing data org.json.JSONException: End of input at character 0 of 
05-21 16:35:46.308: E/JSON RESULT(4278): JSON result: null

谁能发现我在这里做错了什么?我真的很感激任何帮助。

提前致谢!

4

1 回答 1

2

当您尝试解析其中没有任何内容的 JSON 时,会出现您遇到的错误。例如,如果您的手机没有连接到互联网并且您尝试连接到您的服务器,您会看到类似的响应。没有要解析的数据,所以你会得到一个JSONException.

我的猜测是,这与您的 I/O 函数不在后台线程上有关。根据提供的代码,您正在HttpPost主 UI 线程上的 JSONParser 类中运行您的代码。自 API 11 以来,这已被禁止。因此,您将无法解析并抛出JSONException.

尝试将此功能移至AsyncTask. 如果您HttpPost在任务的doInBackground方法中执行您的,您将删除错误。这是AsyncTask. 它们提供了一些有用的代码示例。

an的基本结构AsyncTask如下:

private class DownloadFilesTask extends AsyncTask<URL, Void, Long> {
     protected Long doInBackground(URL... urls) {
        //stuff to do in background 
        return result;
     }

     protected void onPostExecute(Long result) {
        //stuff that runs on the UI thread using the result of background thread 
     }
 }

在此示例中,取自 android 文档,您可以看到许多关键参数。(1) < > 中指示的任务的参数/返回值 (2)doInBackground令人震惊的是,在后台线程上运行的方法 (3) 在onPostExecute方法完成后在 UI 线程上运行的doInBackground方法。onPostExecute将 . 返回的值作为参数doInBackground。如果您注意到,该参数的类型对应于类开头 < > 中的第三种类型。

您将不得不在代码中的确切位置进行调整,但基本思想是,任何 I/O 函数 - 就像您HttpPost在后台线程上发生的那样。任何 UI 更新,例如更改 a 中的文本TextView、使用 aToast或在屏幕上移动东西都发生在onPostExecute. 换句话说,下载您需要的内容doInBackground并将结果(在您的情况下为一些 JSON/字符串)返回到onPostExecute您可以通知用户更改的地方,例如他们是否成功注册。

如何将值传递给 AsyncTask

您在评论中提出了另一个问题,即如何将 a 传递URL给 a AsyncTask。通过用于启动任务AsyncTask的方法将值传递给 an 。execute()一个AsyncTask因为它是它自己的类要求你先创建一个任务的实例

DownloadFilesTask t = new DownloadFilesTask();

创建任务实例后,您可以使用该execute()方法启动任务。在那里您传递您希望任务在doInBackgroundMethod.

t.execute(myUrl);

要传递多个值,只需将它们以逗号分隔

t.execute(myUrl1, myUrl2, myUrl3);

要检索传入的值,您可以从doInBackground方法中访问它们。AsyncTask将所谓的内容作为参数varargs。这些基本上是特定类型的值的列表。在您的情况下,它们将是 URL。要访问它们,您可以按索引获取值。

URL first = urls[0] 

例如,指您传递给AsyncTask. 您用来检索它的名称对应于 . 后面的名称。. . 您提供作为该doInBackground方法的参数。因此,例如,如果您将一个 URL 传递给AsyncTask并希望稍后为您的 getWhatever 方法检索它,您只需使用

getWhatever(urls[0]);

如果有多个 URL,并且这是一个迭代过程,您可以使用 for 循环或任何其他方法通过提供的 URL

于 2013-05-21T15:59:03.350 回答