从 AsyncTask 携带和重用信息(json 字符串)?
Posted
技术标签:
【中文标题】从 AsyncTask 携带和重用信息(json 字符串)?【英文标题】:Carrying and reusing information (json string) from an AsyncTask? 【发布时间】:2019-04-07 00:51:22 【问题描述】:我创建了一个带有 3 个 TextViews 的简单 android 应用,然后通过不同的类运行 AsyncTask 任务,下一步是传递信息并使任务可重用。
任务将使用一个字符串 (URL) 和 MainActivity 的上下文。
任务将发出一个简单的 REST 请求 (GET) 并检索一个 json 字符串。
然后我创建了另一个类,它获取 json 响应并创建一个 .json 文件将其保存到
..../0/Notes/launch.json
“Notes”文件夹是我自己通过file.mkdirs()
创建的。
在 MainActivity 中,我创建了一个 InputStream 来读取 AsyncTask 保存的 .json 文件,但是一旦我尝试打开它,它就会给我一个 FileNotFoundException
。
这是我的 MainActivity.class 的代码
package com.example.root.example;
import android.Manifest;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(this,new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE, 200);
String url = "https://api.spacexdata.com/v3/launches/upcoming"; //Copy the url and open it in your browser to see the json.
AsyncCall asyncCall = new AsyncCall(getApplicationContext());
asyncCall.myAsyncTask(url);
try
InputStream inputStream = this.getAssets().open("launch.json");
int size = inputStream.available();
byte[] buffer = new byte[size];
inputStream.read(buffer);
inputStream.close();
String jsonStringFromFile= new String(buffer,"UTF-8");
JSONObject launchObject = new JSONObject(jsonStringFromFile);
System.out.println(launchObject.get("flight_number"));
catch (IOException e)
e.printStackTrace();
catch (JSONException e)
e.printStackTrace();
这是 AsyncCall.class(制作和检索 json 等)
package com.example.root.example;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class AsyncCall
FileCreator fileCreator = new FileCreator();
private final Context myContext;
public AsyncCall(final Context context)
myContext = context;
public void myAsyncTask(final String url)
AsyncTask asyncTask = new AsyncTask()
@Override
protected Object doInBackground(Object[] objects)
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Response response = null;
try
response = okHttpClient.newCall(request).execute();
fileCreator.generateFile(myContext, myContext.getString(R.string.fileName), response.body().string());
catch (IOException ioe)
ioe.getMessage();
return null;
.execute();
我要归档什么?我正在尝试保存信息(此处为 json)并使其像 Falcon 9 一样可重复使用。
问题在于将信息传递给不同的类。 如果有替代解决方案(除了保存 .json 文件)来解决此问题,请不要犹豫发布它。
这只是我的第一个问题,第二个问题会在您打开 api link 并看到不止一个 JSON 字符串后出现(0,1,2,3,4...即将到来的任务) .
我完全不知道如何解决第一个问题,更不用说第二个问题了,我已经重新开始了几次,前段时间多次。
【问题讨论】:
如果你使用的是okhttp,你不需要asynctask 我正在使用 okhttp。如果没有 asnytask 它将如何工作,因为理论上它会给我一个 networkonmainThread 异常 【参考方案1】:在您的活动中,您可以像这样获取 JSON
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(new Callback()
@Override
public void onResponse(Call call, final Response response) throws IOException
try
final String responseData = response.body().string();
JSONObject json = new JSONObject(responseData);
String flightNumber = json.getString("flight_number");
// TODO: Load number into a TextView
catch (JSONException e)
e.printStackTrace();
);
不过,查看您的 API 响应,您实际上需要 new JSONArray(responseData)
,并且您必须遍历它才能获取每个单独对象的航班号
【讨论】:
这就是问题所在。我需要让它可重复使用。这样我就可以应用下一个任务的航班号的值(如果您访问 api 页面,您会看到有不止 1 个任务即将到来。所以我需要能够获取那些即将到来的任务的 json 字符串也是。但我会定义。试试你的解决方案(没有 asynctask)。 如果你想折射这个,那么new Callback()
可以在任何地方定义。一个单独的类、一个字段、一个局部变量等。这里的重点是.enqueue()
执行后台网络调用而不是加载AsyncTask。关于值,您需要使用JSONArray
,此处给出的答案实际上将无法解析响应
这解决了我的问题。如评论部分所述,您必须将 jsonobject 替换为 jsonarray。您将不得不使用 jsonarray.getJSONObject.... 来访问这些值。以上是关于从 AsyncTask 携带和重用信息(json 字符串)?的主要内容,如果未能解决你的问题,请参考以下文章
Android AsyncTask 无法从 php-mysql 检索 JSON 字符串
如何从 Android AsyncTask 更改活动 UI?