如何使用异步任务向URL发出正确的请求并查找特定元素?

时间:2016-11-26 05:06:18

标签: java android android-asynctask

我最近在我的Android应用中使用了com.(projectname).(projectname).TRetrieve$HttpGetRequest@aed19ea 以及这段代码正在做什么,是对提供的网址发出请求,并从中检索歌曲名称。 (该URL是Spotify歌曲)。当我打印出我得到的回复时,它说

public class HttpGetRequest extends AsyncTask<String, Void, String> {
    public static final String REQUEST_METHOD = "GET";
    public static final int READ_TIMEOUT = 15000;
    public static final int CONNECTION_TIMEOUT = 15000;
    @Override
    protected String doInBackground(String... params){
        String stringUrl = "https://open.spotify.com/track/5Q41NLTmGbVPozwHKK7bk2";
        String result;
        String inputLine;
        try {
            URL myUrl = new URL(stringUrl);
            HttpURLConnection connection = (HttpURLConnection)
                    myUrl.openConnection();
            connection.setRequestMethod(REQUEST_METHOD);
            connection.setReadTimeout(READ_TIMEOUT);
            connection.setConnectTimeout(CONNECTION_TIMEOUT);

            connection.connect();
            InputStreamReader streamReader = new
                    InputStreamReader(connection.getInputStream());
            BufferedReader reader = new BufferedReader(streamReader);
            StringBuilder stringBuilder = new StringBuilder();
            while ((inputLine = reader.readLine()) != null) {
                stringBuilder.append(inputLine);
            }
            reader.close();
            streamReader.close();
            result = stringBuilder.toString();

            linkLoc = result.indexOf(testString) + testString.length();
            for (int i = linkLoc; i < result.indexOf("on Spotify"); i++) {
                sname += result.charAt(i) + "";
            }
        }
        catch(IOException e){
            e.printStackTrace();
            sname = "Error";
        }

        return sname;
    }
    protected void onPostExecute(String result){
        super.onPostExecute(result);
    }

(TRetrieve是执行此请求的类的名称)

如何发出请求并正确获取歌曲的名称?

到目前为止,这是该类的代码:

{{1}}

1 个答案:

答案 0 :(得分:0)

使用AsyncTask / HttpURLConnection与API进行交互是非常老派的。我建议您使用现代方式,使用RxJava / Retrofit / Gson

1)。添加必要的依赖项

将下一个依赖项添加到<root>/app/build.gradle

compile 'com.squareup.okhttp3:okhttp:3.3.1'
compile ('com.squareup.retrofit2:retrofit:2.0.2')
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.google.code.gson:gson:2.4'
compile 'io.reactivex:rxjava:1.0.13'
compile 'io.reactivex:rxandroid:0.25.0'

2)。创建HTTP客户端

2.1)* (这是可选的,仅当您需要在标头中发送AUTH令牌时)
创建拦截器:

import com.betcade.sdk.util.AuthUtil;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

public class DBQRequestInterceptor implements Interceptor {

    public DBQRequestInterceptor(){
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();

        Request.Builder requestBuilder = original.newBuilder();
        if(<if necessary to send a token>){
            requestBuilder.addHeader(<TOKEN_HEADER_NAME>, <TOKEN>);
        }

        Request request = requestBuilder.build();
        return chain.proceed(request);
    }
}

2.2)* (另外,可选步骤,仅当您要记录请求/响应时)
创建日志记录拦截器:

HttpLoggingInterceptor interceptor1 = new HttpLoggingInterceptor();
interceptor1.setLevel(HttpLoggingInterceptor.Level.BODY);

2.3)创建HTTP客户端

OkHttpClient client = new OkHttpClient.Builder()
        .writeTimeout(8, TimeUnit.SECONDS)
        .readTimeout(8, TimeUnit.SECONDS)
        .addInterceptor(interceptor)    // interceptor from step 2.1
        .addInterceptor(interceptor1)   // interceptor from step 2.2
        .build();

2.4)。创建TrackResponse模型:

import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class TrackResponse {

@SerializedName("id")
@Expose
private String id;
@SerializedName("name")
@Expose
private String name;

/**
* 
* @return
* The id
*/
public String getId() {
return id;
}

/**
* 
* @param id
* The id
*/
public void setId(String id) {
this.id = id;
}

/**
* 
* @return
* The name
*/
public String getName() {
return name;
}

/**
* 
* @param name
* The name
*/
public void setName(String name) {
this.name = name;
}

}

2.5)创建interface ApiClient

public interface ApiClient {

    @GET("tracks/{id}")
    Observable<TrackResponse> getTrackInfo(@Path("id") String trackId);
}

2.6)。创建ApiClient的实例:

Retrofit API = new Retrofit.Builder()
        .client(client)
        .baseUrl("https://api.spotify.com/v1/")
        .addConverterFactory(GsonConverterFactory.create(new Gson()))
        .addCallAdapterFactory(RxErrorHandlingCallAdapterFactory.create())
        .build();

ApiClient client = API.create(ApiClient.class);

2.7)。获取名称:

    client.getTrackInfo("5Q41NLTmGbVPozwHKK7bk2")
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<TrackResponse>() {
                @Override
                public void call(TrackResponse trackResponse) {
                    String name = track.getName();
                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    throwable.printStackTrace();
                }
            });