Asynctask无法更新Fragment(Android)中的TextView

时间:2018-10-11 14:13:36

标签: android android-asynctask fragment

当前,我正在一个项目上,在该项目中,我必须对多个片段使用Asynctask。首先,我将Asynctask与Fragment java类分开,并创建了一个新的公共Java类,在其中放置了Asynctask。到目前为止,除最后一部分(也是最重要的部分)外,其他所有东西都可以工作,在该部分,Asynctask需要更新片段视图上的文本视图。

这是片段Java类:

public class DataTabelFragment extends Fragment {

public TextView sensor1;

jsonAsynctask jsonasynctask = new jsonAsynctask(this);


public DataTabelFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // Inflate the layout for this fragment

    View view = inflater.inflate( R.layout.fragment_data_tabel, container, false );

    sensor1 = (TextView) view.findViewById( R.id.sensor1Box );

    new jsonAsynctask(this).execute();

    System.out.println("HEJ MED DIG");

    return view;

}

public void inExecute() {

    for (int i = 0; i < jsonasynctask.allId.size(); i++) {

       sensor1.append( jsonasynctask.allId.get( i ) + " | " + jsonasynctask.allDevice.get( i ) + " | " + jsonasynctask.allTemp.get( i ) + " | " + jsonasynctask.allHum.get( i ) + " | " + jsonasynctask.allBat.get( i ) + " | " + jsonasynctask.allMode.get( i ) + " | " + jsonasynctask.allLux.get( i ) + " | " + jsonasynctask.allDate_time.get( i ) + "\n\n" );

    }

    }

}

这是Java类,在Asynctask中是:

public class jsonAsynctask extends AsyncTask<Void, Void, Void> {

DataTabelFragment dataTabelFragment;

JSONObject idArray, deviceArray, tempArray, humArray, batArray, modeArray, date_timeArray, luxArray;
JSONArray json2;

String basicAuth, line, json_string, json, cxwebURL, credentials, password, username;

String data = "";
String id = "";

List<String> allId = new ArrayList<String>();
List<String> allDevice = new ArrayList<String>();
List<String> allTemp = new ArrayList<String>();
List<String> allHum = new ArrayList<String>();
List<String> allBat = new ArrayList<String>();
List<String> allMode = new ArrayList<String>();
List<String> allDate_time = new ArrayList<String>();
List<String> allLux = new ArrayList<String>();

Gson gson;

ProgressDialog pd;

//HttpsURLConnection connection;
HttpURLConnection connection;
BufferedReader bufferedReader;

URL url;


public jsonAsynctask(DataTabelFragment dataTabelFragment) {
    this.dataTabelFragment = dataTabelFragment;
}

public void inBackground() {

    username = "xxx";
    password = "xxx";

    credentials = username + ":" + password;

    cxwebURL = "https://" + credentials + "@xxx.com/fetch.php?";

    try {

        url = new URL( cxwebURL );

        connection = (HttpsURLConnection) url.openConnection();

        basicAuth = "Basic " + new String( encodeBase64URLSafeString( credentials.getBytes() ) );

        connection.setRequestProperty( "Authorization", basicAuth );
        connection.setRequestMethod( "GET" );
        connection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded" );
        connection.setRequestProperty( "Content-Language", "en-US" );
        connection.setUseCaches( false );
        connection.setDoInput( true );
        connection.setDoOutput( true );
        connection.connect();

        InputStream stream = connection.getInputStream();

        bufferedReader = new BufferedReader( new InputStreamReader( stream ) );

        line = "";

        while (line != null) {
            line = bufferedReader.readLine();
            data = data + line;
        }

        System.out.println( "PRINT DATA HER:  " + data );

        json2 = new JSONArray( data );

        System.out.println( "DET HER ER json2" + json2 );

        for (int i = 0; i < json2.length(); i++) {
            idArray = json2.getJSONObject( i );
            deviceArray = json2.getJSONObject( i );
            tempArray = json2.getJSONObject( i );
            humArray = json2.getJSONObject( i );
            batArray = json2.getJSONObject( i );
            modeArray = json2.getJSONObject( i );
            date_timeArray = json2.getJSONObject( i );
            luxArray = json2.getJSONObject( i );
            id = idArray.getString( "id" );

            String temp = tempArray.getString( "temp" );
            String device = deviceArray.getString( "device" );
            String hum = humArray.getString( "hum" );
            String bat = batArray.getString( "bat" );
            String mode = modeArray.getString( "mode" );
            String date_time = date_timeArray.getString( "time" );
            String lux = luxArray.getString( "light" );

            allId.add( id );
            allDevice.add( device );
            allTemp.add( temp );
            allHum.add( hum );
            allBat.add( bat );
            allMode.add( mode );
            allDate_time.add( date_time );
            allLux.add( lux );

        }

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

}

private static String encodeBase64URLSafeString(byte[] binaryData) {

    return android.util.Base64.encodeToString( binaryData, android.util.Base64.URL_SAFE );

}

@Override
protected Void doInBackground(Void... voids) {

    inBackground();

    return null;
}

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

    //pd = new ProgressDialog( new MainActivity() );
    //pd.setMessage( "Være sød at vente" );
    //pd.setCancelable( false );
    //pd.show();
}

@Override
public void onPostExecute(Void result) {
    super.onPostExecute( result );
        /*
        if (pd.isShowing()) {
            pd.dismiss();
        }*/

    gson = new Gson();

    json = gson.toJson( data );

    json_string = data;

     dataTabelFragment.inExecute();
    }
}

3 个答案:

答案 0 :(得分:2)

在您的示例中,这是asynctask的错误用法。另外,不要将数据保存在asynctask类中以从片段中检索。相反,您应该将数据从asynctask的onPostExecute方法传递给片段。最好的方法是使用asynctask,将其与接口一起使用并通过该接口传递数据。我将举一个例子,希望对您有所帮助。

public class YourFragment extends Fragment implements YourAsyncTask.YourInterface {


    public YourFragment() {
        // Required empty public constructor
    }


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

        View view =  inflater.inflate(R.layout.fragment_your, container, false);



        //do your initial things
        .
        .
        .

        YourAsyncTask yourAsyncTask = new YourAsyncTask(this);
        yourAsyncTask.execute();

        return view;
    }

    @Override
    public void onJobFinishListener(YourDataType yourData) {
        //when this method is trigered by your asynctask 
        //it means that you are in ui thread and update your ui component

        //TODO: update ui component with your data
    }
}

及以下是带有接口参数的asynctask示例:

public class YourAsyncTask extends AsyncTask {

    private YourInterface yourInterfaceListener;

    private YourDataType yourData; //this data should be calculated in doInBackground method and send via interface

    public YourAsyncTask(YourInterface yourInterfaceListener) {
        this.yourInterfaceListener = yourInterfaceListener;
    }

    @Override
    protected Object doInBackground(Object[] objects) {
        //do your all background tasks here
        .
        .
        .
        yourData = do something here to fill your data..

        return null;
    }

    @Override
    protected void onPostExecute(Object o) {
        super.onPostExecute(o);
        yourInterfaceListener.onJobFinishListener(yourData);
    }

    public interface YourInterface{
        void onJobFinishListener(YourDataType yourData);
    }
}

编辑:我在写这篇文章时没有看到以上答案。这也是一个很好的例子

答案 1 :(得分:0)

更好地利用接口。

我也曾在一个项目中使用过几乎相同的场景。

1)创建界面

 public interface AsyncResponse {
        void processFinish(String output);
    }

2)像您一样在异步任务类的构造函数中初始化接口

public jsonAsynctask(AsyncResponse asynctaskResponse) {
    this.asynctaskResponse = asynctaskResponse;
}

3)在片段中实现接口

new jsonAsynctask(new jsonAsynctask.AsyncResponse() {
                                    @Override
                                    public void processFinish(String output) {
                                       //  do whatever you want do here                                          
                                    }
                                }).execute(videouri.toString(), f.getPath());

希望会有所帮助。

答案 2 :(得分:0)

议会采用界面方法解决方案的例子是最好的方法。我还建议在私有的YourInterface yourInterfaceListener上使用WeakReference;

public class YourAsyncTask extends AsyncTask {

private WeakReference<YourInterface> yourInterfaceListener;

private YourDataType yourData; //this data should be calculated in doInBackground method and send via interface

public YourAsyncTask(YourInterface yourInterfaceListener) {
    this.yourInterfaceListener = new WeakReference<YourInterface>(yourInterfaceListener);
}

@Override
protected Object doInBackground(Object[] objects) {
    //do your all background tasks here
    .
    .
    .
    yourData = do something here to fill your data..

    return null;
}

@Override
protected void onPostExecute(Object o) {
    super.onPostExecute(o);
    if(yourInterfaceListener.get()!=null){
        yourInterfaceListener.get().onJobFinishListener(yourData);
    }
}

public interface YourInterface{
    void onJobFinishListener(YourDataType yourData);
}
}