尝试在 TextWatcher 中发出 HTTP 请求

Try to make HTTP request in TextWatcher

有一个编辑文本字段,用户可以在其中插入文本。经过一些延迟程序必须发送 HTTP 请求以获取 JSON 对象。所有适用于 HTTP 请求的方法都运行良好,因为在以前的版本中,所有请求都是通过按下按钮发送的。现在我想删除 "SEND" 按钮并希望程序自己发送请求。但是我得到了一个错误。需要了解我需要如何修改代码才能使其正常工作。

public class MainActivity extends AppCompatActivity {

    AppCompatButton translateButton;
    AppCompatButton chooseLanguageButton;
    AppCompatEditText translatedTextOutput;
    AppCompatEditText translatedTextInput;
    String translatedInputString;
    RequestQueue requestQueue;
    SharedPreferences sPref;
    final String SAVED_TEXT = "saved_text";
    final String TAG = "myTag";

    private ProgressBar progressBar;
    private Timer timer;

    private TextWatcher searchTextWatcher = new TextWatcher() {
        @Override
        public void afterTextChanged(Editable arg0) {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    sendJsonRequest();
                }
            }, 600);
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (timer != null) {
                timer.cancel();
            }
        }
    };

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

        translateButton = (AppCompatButton) findViewById(R.id.button_ok);
        chooseLanguageButton = (AppCompatButton) findViewById(R.id.choose_language_button);
        translatedTextOutput = (AppCompatEditText) findViewById(R.id.translated_text_field);
        translatedTextInput = (AppCompatEditText) findViewById(R.id.translation_input_edit);
        translatedTextInput.addTextChangedListener(searchTextWatcher);

        translateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.v(TAG, "Inside onClick");
                requestQueue = Volley.newRequestQueue(MainActivity.this);
                sendJsonRequest();
            }
        });

        chooseLanguageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                saveText();
                Intent intent = new Intent(MainActivity.this, ChooseLanguageList.class);
                startActivity(intent);
            }
        });

        loadText();
    }

    void saveText() {
        sPref = getPreferences(MODE_PRIVATE);
        SharedPreferences.Editor ed = sPref.edit();
        ed.putString(SAVED_TEXT, translatedTextInput.getText().toString());
        ed.commit();
        Toast.makeText(this, "Text saved", Toast.LENGTH_SHORT).show();
    }

    void loadText() {
        sPref = getPreferences(MODE_PRIVATE);
        String savedText = sPref.getString(SAVED_TEXT, "");
        translatedTextInput.setText(savedText);
        Toast.makeText(this, "Text loaded", Toast.LENGTH_SHORT).show();
    }


    public void sendJsonRequest() {
        Intent myIntent = getIntent();
        String language = myIntent.getStringExtra("short");
        Log.v(getClass().getSimpleName(), "language short = " + language);
        translatedInputString = translatedTextInput.getText().toString();
        String url = String.format(getApplicationContext().getResources().getString(R.string.request_template),
                String.format(getApplicationContext().getResources().getString(R.string.query_Template), translatedInputString, language ));
        JsonObjectRequest jsObjRequest = new JsonObjectRequest
        (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Log.v(TAG, "Inside OnResponse" + response.toString());
                JSONArray results = null;
                try {
                    results = response.getJSONObject("data").getJSONArray("translations");
                    for (int i=0,j=results.length();i<j;i++) {
                        String webTitle = results.getJSONObject(i).getString("translatedText");
                        translatedTextOutput.setText(webTitle);
                    }
                } catch (JSONException e) {
                    Log.e(TAG, "Error :" + e);
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                if (error instanceof NetworkError) {
                    Log.e(TAG, "NetworkError");
                } else if (error instanceof ServerError) {
                    Log.e(TAG, "The server could not be found. Please try again after some time!!");
                } else if (error instanceof AuthFailureError) {
                    Log.e(TAG, "AuthFailureError");
                } else if (error instanceof ParseError) {
                    Log.e(TAG, "Parsing error! Please try again after some time!!");
                } else if (error instanceof NoConnectionError) {
                    Log.e(TAG, "NoConnectionError!");
                } else if (error instanceof TimeoutError) {
                    Log.e(TAG, "Connection TimeOut! Please check your internet connection.");
                }
            }
        });
        requestQueue.add(jsObjRequest);
    }

}

错误代码为

 E/AndroidRuntime: FATAL EXCEPTION: Timer-0
    Process: com.borisruzanov.volleyexample, PID: 3630
    java.lang.NullPointerException: Attempt to invoke virtual method 'com.android.volley.Request com.android.volley.RequestQueue.add(com.android.volley.Request)' on a null object reference
    at com.borisruzanov.volleyexample.MainActivity.sendJsonRequest(MainActivity.java:167)
    at com.borisruzanov.volleyexample.MainActivity.run(MainActivity.java:58)
    at java.util.Timer$TimerImpl.run(Timer.java:284)
    W/EGL_emulation: eglSurfaceAttrib not implemented
    W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe975ad80, error=EGL_SUCCESS
    I/Choreographer: Skipped 32 frames!  The application may be doing too much work on its main thread.
    I/Choreographer: Skipped 114 frames!  The application may be doing too much work on its main thread.
    E/Surface: getSlotFromBufferLocked: unknown buffer: 0xeae69c70
    E/Surface: getSlotFromBufferLocked: unknown buffer: 0xeae69ce0

    [ 11-01 14:58:12.135   936:  948 D/         ]
    HostConnection::get() New Host Connection established 0xd8bbab70, tid 948

发生这种情况是因为您仅在单击 translateButton 时才创建 RequestQueue。 将此行移到 OnClickListener:

之外

requestQueue = Volley.newRequestQueue(MainActivity.this);

还可以考虑使用 documentation 推荐的单例模式。