异步任务后无法更改文本

时间:2014-07-05 10:24:55

标签: java android asynchronous android-fragments android-asynctask

我正在开发Android应用程序。它使用异步任务连接到Internet并获取JSON结果。之后,它将值保存到私有String变量。此任务适用于片段类中的按钮侦听器。单击按钮后,执行异步任务。下一个命令是setText到TextView。异步任务运行良好,但没有出现任何问题。如果我开始偏好活动然后回来,它就在那里。所以它有效,但它没有出现。也许我必须“重画”屏幕,但我不知道如何。还是其他一些想法?请帮忙。

我在Eclipse / Android工作室中创建了基本的android项目,其中我有MainActivity类,而PlaceholderFragment类正在扩展Fragment(在XML中没有Fragment标记 - activity_main.xml是FrameLayout而fragment_main.xml是Linear Layout)。首先,类PlaceholderFragment是内部静态类,但我把它推出来分隔.java文件。看看我的代码,我试着简化它:

MainActivity.java

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

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

// URL to get JSON
private static String pref_url;
private static String pref_key;
private static String pref_check;

private String status = " ";

private static final String PARAM_KEY = "key";
private static final String PARAM_CODE = "code";
private static final String PARAM_CHECK = "check";

// JSON Node Names
private static final String TAG_STATUS = "status";

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

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }
}

public void btnDoIt() {
    new JSONParse().execute();
}

public String getStatus() {
    return status;
}

public String createUrl() {
    String url = pref_url + "?" + PARAM_KEY + "=" + pref_key + "&"
            + PARAM_CODE + "=" + Code + "&" + PARAM_CHECK + "="
            + pref_check;
    return url;
}

 private class JSONParse extends AsyncTask<String, String, JSONObject> {
    private ProgressDialog pDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Getting Data ...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();

    }

    @Override
    protected JSONObject doInBackground(String... args) {

        // Getting JSON from URL

        JSONParser jParser = new JSONParser();
        JSONObject json = jParser.getJSONFromUrl(createUrl());

        return json;

    }

    @Override
    protected void onPostExecute(JSONObject json) {
        pDialog.dismiss();
        try {
            // Storing JSON item in a Variable
            String vypis_key = json.getString(TAG_KEY);
            status = json.getString(TAG_STATUS);

            Toast toast = Toast.makeText(getApplicationContext(),
                    "//KEY = " + vypis_key, Toast.LENGTH_LONG);
            toast.show();   //it writes KEY = OK 

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

PlaceholderFragment.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class PlaceholderFragment extends Fragment {

View rootView;
Button btngetdata;


public PlaceholderFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.fragment_main, container, false);

    btngetdata = (Button) rootView.findViewById(R.id.btnUplatni);
    btngetdata.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((MainActivity) getActivity()).btnDoIt();
            setTextInTextView(getString(R.string.text_status) + " " + ((MainActivity) getActivity()).getStatus(), R.id.textstatus);
        }
    });

    return rootView;
}


@Override
public void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    setTextInTextView(getString(R.string.text_status) + " " + ((MainActivity) getActivity()).getStatus(), R.id.textstatus);
}

public void setTextInTextView(String text, int id) {
    TextView textView = (TextView) rootView.findViewById(id);
    textView.setText(text);
}

fragment_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.zonemedia.skener.PlaceholderFragment" >

    <TextView
        android:id="@+id/textstatus"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/text_status" />

    <Button
        android:id="@+id/btnUplatni"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_Uplatni" />

</LinearLayout>

activity_main.xml中

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.zonemedia.skener.MainActivity"
tools:ignore="MergeRootFrame" >

3 个答案:

答案 0 :(得分:2)

问题是您在onclick()

中执行以下操作
       ((MainActivity) getActivity()).btnDoIt();
        setTextInTextView(getString(R.string.text_status) + " " + ((MainActivity)         getActivity()).getStatus(), R.id.textstatus);

当执行第二条指令时,第一条指令(异步任务)仍在执行中。

我建议你使用活动中的状态创建一个回调,并在asynctask的onPostExecute中调用它,而不是在此回调中更改textview。

答案 1 :(得分:0)

您正在更新AsyncTask的onPostExecute方法中的状态。并在调用AsyncTask后获取状态,因此它不会更新状态文本。

因此,onPostExecute执行AsyncTask方法更新状态文本。即

只需更改

((MainActivity) getActivity()).btnDoIt();
        setTextInTextView(getString(R.string.text_status) + " " + ((MainActivity) getActivity()).getStatus(), R.id.textstatus);

((MainActivity) getActivity()).btnDoIt();

并将您的onPostExecute方法重写为

   @Override
    protected void onPostExecute(JSONObject json) {
        pDialog.dismiss();
        try {
            // Storing JSON item in a Variable
            String vypis_key = json.getString(TAG_KEY);
            status = json.getString(TAG_STATUS);

            Toast toast = Toast.makeText(getApplicationContext(),
                    "//KEY = " + vypis_key, Toast.LENGTH_LONG);
            toast.show();   //it writes KEY = OK 

            FragmentManager fm = getSupportFragmentManager();
            PlaceholderFragment fragment = (PlaceholderFragmen)fm.findFragmentById(R.id.fragment_main);
            fragment.setTextInTextView(getString(R.string.text_status) + " " + getStatus());
} catch (JSONException e) {
            e.printStackTrace();
        }
    }

修改

在片段的OncreateView方法中初始化textview,并在Fragment类中声明为TextView textView;

 TextView textView;
 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        rootView = inflater.inflate(R.layout.fragment_main, container, false);

        textView = (TextView) rootView.findViewById(R.id.textstatus);
    //rest code

并将setTextInTextViewmethod重写为

public void setTextInTextView(String text) {
    textView.setText(text);
}

答案 2 :(得分:0)

你的getStatus()方法返回你设置的值为&#34; &#34;

尝试更新onPostExecute方法,将status的值设置为&#34; vypis_key&#34;变量。这将有效,但只有在AsyncTask完成后才需要提供一种方法来确保在更新TextView之前已经发生过。