使用MVP模型编写“登录”应用程序时遇到问题

时间:2018-05-27 17:22:24

标签: android networking android-asynctask android-mvp

我尝试使用MVP模型编写“登录”应用程序。我使用WAMP来构建我的服务器。我确定我的php文档没有问题。

这是我的应用程序的结构: enter image description here

以下是文件:

User.java

package com.example.android.login.mvp;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.presenter.UserLoginPresenter;
import com.example.android.login.mvp.view.IUserLoginView;

public class UserLoginActivity extends AppCompatActivity implements IUserLoginView
{


    private EditText mEtUsername, mEtPassword;
    private Button mBtnLogin, mBtnClear;
    private ProgressBar mPbLoading;

    private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);

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

        initViews();
    }

    private void initViews()
    {
        mEtUsername = (EditText) findViewById(R.id.id_et_username);
        mEtPassword = (EditText) findViewById(R.id.id_et_password);

        mBtnClear = (Button) findViewById(R.id.id_btn_clear);
        mBtnLogin = (Button) findViewById(R.id.id_btn_login);

        mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);

        mBtnLogin.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mUserLoginPresenter.login();
            }
        });

        mBtnClear.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mUserLoginPresenter.clear();
            }
        });
    }


    @Override
    public String getUserName()
    {
        return mEtUsername.getText().toString();
    }

    @Override
    public String getPassword()
    {
        return mEtPassword.getText().toString();
    }

    @Override
    public void clearUserName()
    {
        mEtUsername.setText("");
    }

    @Override
    public void clearPassword()
    {
        mEtPassword.setText("");
    }

    @Override
    public void showLoading()
    {
        mPbLoading.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading()
    {
        mPbLoading.setVisibility(View.GONE);
    }

    @Override
    public void toMainActivity(User user)
    {
        Toast.makeText(this, user.getUsername() +
                " login success , to MainActivity", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showFailedError()
    {
        Toast.makeText(this,
                "login failed", Toast.LENGTH_SHORT).show();
    }
}

IUserBiz.java

package com.example.android.login.mvp.biz;

/**
 * Created by zhy on 15/6/19.
 */
public interface IUserBiz
{
    public void login(String username, String password, OnLoginListener loginListener);
}

OnLoginListener.java

package com.example.android.login.mvp.biz;

import com.example.android.login.mvp.bean.User;

/**
 * Created by zhy on 15/6/19.
 */
public interface OnLoginListener
{
    void loginSuccess(User user);

    void loginFailed();
}

UserBiz.java

package com.example.android.login.mvp.biz;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;

/**
 * Created by zhy on 15/6/19.
 */
public class UserBiz extends AppCompatActivity implements IUserBiz
{
    private User user;
    private OnLoginListener loginListener;

    @Override
    public void login(final String username, final String password, final OnLoginListener mLoginListener)
    {
        user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setStatus(0);
        loginListener = mLoginListener;

        LoginAsyncTask task = new LoginAsyncTask();
        String test1Url = getString(R.string.server_ip)+"/server/login.php";
        task.execute(test1Url);
    }

    /**
     * Update the UI with the given earthquake information.
     */
    private void updateUi(User mUser) {
        if (mUser.getStatus()==1)
        {
            loginListener.loginSuccess(user);
        } else
        {
            loginListener.loginFailed();
        }
    }

    private class LoginAsyncTask extends AsyncTask<String, Void, User> {

        @Override
        protected User doInBackground(String... urls) {
            if (urls.length < 1 || urls[0] == null) {
                return null;
            }
            // Perform the HTTP request for earthquake data and process the response.
            User mUser = Utils.fetchEarthquakeData(urls[0],user);
            return mUser;
        }

        @Override
        protected void onPostExecute(User result) {
            if(result==null){
                return;
            }
            updateUi(result);
        }
    }

}

Utils.java

package com.example.android.login.mvp.biz;

import android.text.TextUtils;
import android.util.Log;

import com.example.android.login.mvp.bean.User;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;

/**
 * Utility class with methods to help perform the HTTP request and
 * parse the response.
 */
public final class Utils {

    /** Tag for the log messages */
    public static final String LOG_TAG = Utils.class.getSimpleName();

    /**
     * Query the USGS dataset and return an {@link User} object to represent a single earthquake.
     */
    public static User fetchEarthquakeData(String requestUrl, User user) {
        // Create URL object
        URL url = createUrl(requestUrl);

        // Perform HTTP request to the URL and receive a JSON response back
        String jsonResponse = null;
        try {
            jsonResponse = makeHttpRequest(url, user);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error closing input stream", e);
        }

        // Extract relevant fields from the JSON response and create an {@link User} object
        User earthquake = extractFeatureFromJson(jsonResponse);

        // Return the {@link User}
        return earthquake;
    }

    /**
     * Returns new URL object from the given string URL.
     */
    private static URL createUrl(String stringUrl) {
        URL url = null;
        try {
            url = new URL(stringUrl);
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Error with creating URL ", e);
        }
        return url;
    }

    /**
     * Make an HTTP request to the given URL and return a String as the response.
     */
    private static String makeHttpRequest(URL url, User user) throws IOException {
        String jsonResponse = "";

        // If the URL is null, then return early.
        if (url == null) {
            return jsonResponse;
        }

        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setReadTimeout(10000 /* milliseconds */);
            urlConnection.setConnectTimeout(15000 /* milliseconds */);
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoOutput(true);
            String params="app_user_name="+user.getUsername()+'&'+"app_password="+user.getPassword();
            OutputStream out=urlConnection.getOutputStream();
            out.write(params.getBytes());//post提交参数
            out.flush();
            out.close();

            // If the request was successful (response code 200),
            // then read the input stream and parse the response.
            if (urlConnection.getResponseCode() == 200) {
                inputStream = urlConnection.getInputStream();
                jsonResponse = readFromStream(inputStream);
            } else {
                Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
            }
        } catch (IOException e) {
            Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return jsonResponse;
    }

    /**
     * Convert the {@link InputStream} into a String which contains the
     * whole JSON response from the server.
     */
    private static String readFromStream(InputStream inputStream) throws IOException {
        StringBuilder output = new StringBuilder();
        if (inputStream != null) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
            BufferedReader reader = new BufferedReader(inputStreamReader);
            String line = reader.readLine();
            while (line != null) {
                output.append(line);
                line = reader.readLine();
            }
        }
        return output.toString();
    }

    /**
     * Return an {@link User} object by parsing out information
     * about the first earthquake from the input earthquakeJSON string.
     */
    private static User extractFeatureFromJson(String earthquakeJSON) {
        // If the JSON string is empty or null, then return early.
        if (TextUtils.isEmpty(earthquakeJSON)) {
            return null;
        }

        try {
            JSONObject baseJsonResponse = new JSONObject(earthquakeJSON);

            // If there are results in the features array
            if (baseJsonResponse.length() > 0) {

                int status = baseJsonResponse.getInt("status");

                // Create a new {@link User} object
                User user=new User();
                user.setStatus(status);
                return user;
            }
        } catch (JSONException e) {
            Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
        }
        return null;
    }
}

UserLoginPresenter.java

package com.example.android.login.mvp.presenter;

import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.biz.IUserBiz;
import com.example.android.login.mvp.biz.OnLoginListener;
import com.example.android.login.mvp.biz.UserBiz;
import com.example.android.login.mvp.view.IUserLoginView;

/**
 * Created by zhy on 15/6/19.
 */
public class UserLoginPresenter {
    private IUserBiz userBiz;
    private IUserLoginView userLoginView;

    public UserLoginPresenter(IUserLoginView userLoginView) {
        this.userLoginView = userLoginView;
        this.userBiz = new UserBiz();
    }

    public void login() {
        userLoginView.showLoading();
        userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() {
            @Override
            public void loginSuccess(final User user) {
                userLoginView.toMainActivity(user);
                userLoginView.hideLoading();
            }

            @Override
            public void loginFailed() {
                userLoginView.showFailedError();
                userLoginView.hideLoading();
            }
        });
    }

    public void clear() {
        userLoginView.clearUserName();
        userLoginView.clearPassword();
    }


}

IUserLoginView.java

package com.example.android.login.mvp.view;

import com.example.android.login.mvp.bean.User;

/**
 * Created by zhy on 15/6/19.
 */
public interface IUserLoginView
{
    String getUserName();

    String getPassword();

    void clearUserName();

    void clearPassword();

    void showLoading();

    void hideLoading();

    void toMainActivity(User user);

    void showFailedError();

}

UserLoginActivity.java

package com.example.android.login.mvp;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.presenter.UserLoginPresenter;
import com.example.android.login.mvp.view.IUserLoginView;

public class UserLoginActivity extends AppCompatActivity implements IUserLoginView
{


    private EditText mEtUsername, mEtPassword;
    private Button mBtnLogin, mBtnClear;
    private ProgressBar mPbLoading;

    private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);

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

        initViews();
    }

    private void initViews()
    {
        mEtUsername = (EditText) findViewById(R.id.id_et_username);
        mEtPassword = (EditText) findViewById(R.id.id_et_password);

        mBtnClear = (Button) findViewById(R.id.id_btn_clear);
        mBtnLogin = (Button) findViewById(R.id.id_btn_login);

        mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);

        mBtnLogin.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mUserLoginPresenter.login();
            }
        });

        mBtnClear.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mUserLoginPresenter.clear();
            }
        });
    }


    @Override
    public String getUserName()
    {
        return mEtUsername.getText().toString();
    }

    @Override
    public String getPassword()
    {
        return mEtPassword.getText().toString();
    }

    @Override
    public void clearUserName()
    {
        mEtUsername.setText("");
    }

    @Override
    public void clearPassword()
    {
        mEtPassword.setText("");
    }

    @Override
    public void showLoading()
    {
        mPbLoading.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading()
    {
        mPbLoading.setVisibility(View.GONE);
    }

    @Override
    public void toMainActivity(User user)
    {
        Toast.makeText(this, user.getUsername() +
                " login success , to MainActivity", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showFailedError()
    {
        Toast.makeText(this,
                "login failed", Toast.LENGTH_SHORT).show();
    }
}

但我这样做错了: enter image description here

我不知道。怎么解决?

1 个答案:

答案 0 :(得分:1)

问题出在这里     this.userBiz = new UserBiz();

UserBiz是一个活动,因此活动在使用Intent(通过操作系统)启动时获取其上下文,但创建活动对象将不提供任何contenxt,因此

  @Override
    public void login(final String username, final String password, final OnLoginListener mLoginListener)
    {
        user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setStatus(0);
        loginListener = mLoginListener;

        LoginAsyncTask task = new LoginAsyncTask();
        String test1Url = getString(R.string.server_ip)+"/server/login.php";
        // no context here due to new UserBiz
        // getString required context
        task.execute(test1Url);
    }

解决方案:您可以使用枚举或静态最终常量来避免上下文,并且明智地将UserBiz替换为单独的类而不是活动