当前,我正在一个项目上,在该项目中,我必须对多个片段使用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();
}
}
答案 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);
}
}