【问题标题】:Asynctask not updating TextView in Fragment (Android)Asynctask 不更新 Fragment 中的 TextView (Android)
【发布时间】:2018-10-11 14:13:36
【问题描述】:

目前,我正在做一个项目,我必须在多个片段上使用 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" );

    }

    }

}

这是 Asynctask 中的 Java 类:

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();
    }
}

【问题讨论】:

  • 您确定您的 ArrayLists 确实包含数据吗?
  • 是的,我有系统输出打印显示我其中的数据。也感谢您的宝贵时间!
  • 尝试在您的inExecute() 方法中使用getActivity().runOnUiThread()
  • 这就是它所说的,当我在我的 inExecute() 方法中使用它时。必需:可运行。找到:没有参数
  • 是的,您也必须放入 Runnable。看看如何做到这一点。

标签: android android-asynctask fragment


【解决方案1】:

在您的示例中,这是对 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
    }
}

下面是一个带有接口参数的异步任务示例:

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);
    }
}

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

【讨论】:

  • 感谢您的回答!你能否详细说明一下,YourDataType 和 yourData,我不确定我应该在这里做什么。抱歉,我是 Android 新手。
  • 在您的示例中 YourDataType yourData 将是 List allId
【解决方案2】:

更好地利用接口。

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

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());

希望它会有所帮助。

【讨论】:

    【解决方案3】:

    议会的接口方法解决方案示例是最好的方法。我还建议在私有 YourInterface yourInterfaceListener 上使用 Wea​​kReference;

    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);
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多