我试图用 安卓网络 lib。
这是我的初始化方法。
public class TestLabApp extends Application {
@Override
public void onCreate() {
super.onCreate();
//For logging
RealInterceptor realInterceptor = new RealInterceptor();
realInterceptor.enableLoggingForBody(true);
realInterceptor.enableLoggingForUrl(true);
realInterceptor.enableLoggingForHeaders(true);
realInterceptor.enableLoggingForHttpStatusCodes(true);
realInterceptor.enableLoggingForExecutionTime(false);
//Add logging to okHttpClient
OkHttpClient okHttpClient = new OkHttpClient()
.newBuilder()
.addNetworkInterceptor(realInterceptor)
.build();
//Init AndroidNetworking lib with the okHttpClient (with aloggint interceptor)
AndroidNetworking.initialize(getApplicationContext(), okHttpClient);
}
}
我把这个也加到了清单里。
<application
android:name=".TestLabApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
这是我自己的拦截器 因为文档中的那个例子根本不是lib的一部分。
public class RealInterceptor implements Interceptor {
private boolean logUrl = true;
private boolean logBody = true;
private boolean logHeaders = true;
private boolean logHttpStatusCodes = true;
private boolean logExecutionTime = true;
public void enableLoggingForUrl(boolean logUrl) {
this.logUrl = logUrl;
}
public void enableLoggingForHeaders(boolean logHeaders) {
this.logHeaders = logHeaders;
}
public void enableLoggingForBody(boolean logBody) {
this.logBody = logBody;
}
public void enableLoggingForHttpStatusCodes(boolean logHttpStatusCodes) {
this.logHttpStatusCodes = logHttpStatusCodes;
}
public void enableLoggingForExecutionTime(boolean logExecutionTime) {
this.logExecutionTime = logExecutionTime;
}
private void logInfo(Object o) {
Log.i(getClass().getSimpleName(), o.toString());
}
private void logError(Object o) {
Log.e(getClass().getSimpleName(), o.toString());
}
@Override
public Response intercept(Chain chain) throws IOException {
StringBuilder sb = new StringBuilder();
Request request = chain.request();
RequestBody requestBody = request.body();
boolean hasRequestBody = requestBody != null;
if (logUrl) {
sb.append("\nURL: " + request.url());
}
if (logBody) {
if (hasRequestBody) {
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
String bodyParams = buffer.readString(Charset.forName("UTF-8"));
bodyParams = bodyParams.replace("&", "\nParam: ");
sb.append("\nParam: " + bodyParams);
} else {
sb.append("\nParam: <No params>");
}
}
if (logHeaders) {
Headers headers = request.headers();
String headersStr = "";
for (int i = 0, count = headers.size(); i < count; i++) {
headersStr += "\nHeader: " + headers.name(i) + ": " + headers.value(i);
}
sb.append(headersStr);
}
long startNs = System.nanoTime();
Response response;
try {
response = chain.proceed(request);
} catch (Exception e) {
throw e;
}
if (logHttpStatusCodes) {
sb.append("\nHTTP Status code: " + response.code());
}
long tookSec = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startNs);
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
if (logExecutionTime) {
if (tookSec > 1) {
sb.append("\nExecution time: " + tookSec + " sec");
} else {
sb.append("\nExecution time: " + tookMs + " ms");
}
}
if (response.code() != 200) {
logError(sb.toString());
} else {
logInfo(sb.toString());
}
return response;
}
}
我是如何尝试使用它的。
AndroidNetworking.post("http://myurlishere.hu/api/test-result/save")
.addBodyParameter("param_1", "12345")
.addBodyParameter("param_2", "abcdef")
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
@Override
public void onResponse(JSONObject response) {
// do anything with response
Log.i("RESP___", response.toString());
codeTv.setText(getString(R.string.please_read_the_qr_code));
enableControls(true);
progressBar.setVisibility(View.INVISIBLE);
zBarScannerView.resumeCameraPreview(MainActivity.this);
Toast.makeText(MainActivity.this, "API done", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(ANError error) {
// handle error
codeTv.setText(getString(R.string.please_read_the_qr_code));
enableControls(true);
progressBar.setVisibility(View.INVISIBLE);
zBarScannerView.resumeCameraPreview(MainActivity.this);
DialogHelper.showInfo(MainActivity.this, "Error: Body: "+error.getErrorBody()+", Response: "+error.getResponse()+", Detail: "+error.getErrorDetail()+", Code: "+error.getErrorCode());
}
});
问题是:
我没有看到任何关于发生了什么的日志。为什么会这样?
你的代码看起来很好,但是我可以给你建议其他的日志记录方案。
首先,它不需要创建自己的日志,因为已经有了。package okhttp3.logging
提供 HttpLoggingInterceptor
它记录了所有你在你的 RealInterceptor
.
这里有一个替代解决方案 :
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
okHttpClientBuilder!!.addInterceptor(logging)
在你的情况下 :
//Add logging to okHttpClient
var okHttpClient = OkHttpClient()
.newBuilder()
.addNetworkInterceptor(logging)
.build()
希望这对你有帮助,如果是应用程序的发布模式,你可以通过添加条件来禁止日志记录。
var okHttpClientBuilder = OkHttpClient()
.newBuilder()
if (BuildConfig.DEBUG) {
okHttpClientBuilder.addNetworkInterceptor(logging)
}
var okHttpClient = okHttpClientBuilder.build()
网络拦截器
能够对重定向和重试等中间响应进行操作。
不调用对网络短路的缓存响应。
在数据将在网络上传输时就观察数据。
访问承载请求的Connection。
我认为你的请求有一个缓存和 NetworkInterceptor
将无法工作。尝试使用 addInterceptor
而不是 addNetworkInterceptor
. 它可以正常工作。
我想你可能缺少一个无参数构造函数,因为你的 new
关键字需要它。
public RealInterceptor() {}
尝试添加它,它应该会返回一个实例。但最好换成Retrofit2,从一些明显被废弃的库,大约有200个开放的问题;在那里你可以使用同样的 Interceptor
.
我不太明白,为什么你要实施 Interceptor
并使你自己的实现的 Interceptor
? 比如你需要一些库本身没有提供的自定义日志功能?
如果你需要的只是记录请求响应的头和正文,那么在这个库中,你可以使用 README
文件中提到,你可以通过简单地启用日志记录来实现。
AndroidNetworking.enableLogging(); // simply enable logging
AndroidNetworking.enableLogging(LEVEL.HEADERS); // enabling logging with level
似乎有不同的级别,你可以提供。
public enum Level {
/**
* No logs.
*/
NONE,
/**
* Logs request and response lines.
* <p>
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1 (3-byte body)
*
* <-- 200 OK (22ms, 6-byte body)
* }</pre>
*/
BASIC,
/**
* Logs request and response lines and their respective headers.
* <p>
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
* --> END POST
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
* <-- END HTTP
* }</pre>
*/
HEADERS,
/**
* Logs request and response lines and their respective headers and bodies (if present).
* <p>
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
*
* Hi?
* --> END POST
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
*
* Hello!
* <-- END HTTP
* }</pre>
*/
BODY
}
让我知道,如果这对你有用。祝你愉快:)