آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

استفاده از کتابخانه OkHttp در یک متد با مقدار برگشتی String

Hadi  9 سال پیش  9 سال پیش
+1 0

سلام. دوستان من بعد اینکه آموزش نوت رو دیدم.سعی کردم که ارتباط با اینترنت رو با استفاده از کتابخانه OkHttp انحام بدم. موفق هم شدم. اما الان سوالی برام پیش اومده. من برای استفاده از کتابخونه یک متد تعریف کردم که مقدار استرینگ رو بهم بر میگردونه. از طریق روش ناهمزمان و از طریق ترد UI از کتابخونه استفاده کردم. اما مشکل اینکه من بعد از اینکه درخواست ام رو اجرا می کنم و به خط برگرداندن string  می رسم. مقدار null هست. برای حل این مشکل گفتم که اگر مقدارش null بود. 5 میلی ثانیه صبر کن و بعد دوباره چک کن. اگر null نبود. میره به خط return کردن string. کد درست هم کار میکنه. اما آیا روش بهتری هم هست؟یا اینکه آیا به صرفه هست که از این روش برم؟منظورم بخشی از کد هست که اگر استرینگ نال بود وایسه.ممنون

 
private static String string;
public static String startUrl(final String urlAddrass) {

Log.i("Log", "WebService is running");
OkHttpClient client = new OkHttpClient();

// 2
Request request = new Request.Builder()
.url(urlAddrass)
.build();

// 3
Callback callback = new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
// manage error
Log.e("Log", "Unexpected code " + response);
return;
}

// show body content
string = response.body().string();
}
};

// 6
client.newCall(request).enqueue(callback);
while(string == null){
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i("Log" , "json: " + string);
return string;
}
 
0 0
رابیت جان ممنونم از جوابت اما اینکه گفتی اگه بیشتر طول بکشه متغیر نال هست،اشتباهه چون گفتم تا زمانی که نال هست ۵ میلی ثانیه صبر کن و دوباره چکش کن.اکر نال نبود میره خط رترن کردن. اما اگر برای هر بار که می خوام به اینترنت متصل شم و کاری کنم، این همه کد رو دوباره بنویسم و کد هایی بعدیمو داخل onResponse بنویسم.فکر نکنم بهینه باشه.هر چند این کد ایراداتی داره.اما اینی که شما گفتید فکر کنم نیست. (9 سال پیش)
0 0
در مورد اول حق با شماست ولی باز هم مسئله اتلاف وقت رو داره. اما برای بهینه بودن الان این روش اصلا ناهمزمان حساب نمیشه. ناهمزمانی یعنی دیگه ما منتظر جواب نمونیم و وقتی جواب از سمت سرور اومد یکسری اتفاق‌ها بیفته. توی این روش بازم شما منتظر میمونی تا جواب از سمت سرور بیاد که به قول خودتون بهینه نیست. و اینکه کدهاتون رو داخل onResponse بنویسید روش اصلی هست که باید استفاده بشه. ماهیت وجود این متد اینه که وقتی جواب اومد ما کارهایی که میخوایم رو انجام بدیم و دیگه منتظر اومدن جواب نباشیم. متوجه نمیشم چه کدهایی رو باید دوباره بنویسید؟ چیزی که من فهمیدم اینه که شما میخواید Json دریافتی رو return کنید و هربار هم میخواید json رو از سرور بگیرید و برای اینکار باید یک درخواست به سرور بفرستید پس هربار متد startUrl صدا میشه و کدهاش اجرا میشه، دیگه تفاوتی نمیکنه کد داخل onResponse باشه یا خارج (9 سال پیش)
0 0
بله درست متوجه شدید. من میخواهم هر بار که متدم اجرا میشه مقدار json رو بهم بده. متنها مشکل من هم همین return کردن هست. تو کد پایین که نوشتید دیدم که return کردن رو داخل onResponse گذاشتید. در صورتی که این متد خروجی نداره. اگر میتونستم مقدار دریافتی از سایت رو return کنم بدون استفاده از چک کردن null بودن string خوب میشد. موندم چیکار کنم. (9 سال پیش)
+1 0
حق با شماست، اشتباه از من بود. من خودم چون از RxJava استفاده می‌کنم این مشکل رو ندارم و برای onResponse وقتی مقدار آماده شد خودش جواب رو برمیگردونه. ولی شما دو راه دارید یکی اینکه هربار call رو انجام بدید. در اینصورت حجم کدتون بالا میره اما بهتر از این هست که از sleep استفاده کنید. اما راه استاندارد و بهتر هم استفاده از callback هست که من جواب پایین رو آپدیت می‌کنم و اون رو قرار میدم. (9 سال پیش)
 برای این سوال 1 پاسخ وجود دارد. مشاهده پاسخ صحیح
پاسخ به سوال 
Rabbit  9 سال پیش
+1 0

 پاسخ صحیح

نباید متغیر string رو خارج از onResponse ازش استفاده کنی. 

با استفاده از interface  یک callback می‌سازیم. callback در واقع همون عملکرد RxJava رو پیاده می‌کنه و برنامه غیرهمزمان میشه به اینصورت که میگیم هر زمان string آماده بود این متد رو اجرا کن.


public class HttpRequests{
public static String startUrl(final String urlAddrass,final HttpCallback httpCallback) {
  OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(urlAddrass)
.build();
Callback callback = new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStac kTrace();
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
// manage error
Log.e("Log", "Unexpected code " + response);
return;
}

// show body content
String string = response.body().string();
Log.i("Log" , "json: " + string);

httpCallback.onSuccess(string);
}
};

client.newCall(request).enqueue(callback);

}

public interface HttpCallback {
public void onSuccess(String response);
}
}

حالا کافیه به شکل زیر درخواست رو هرجا نیاز داری انجام بدی:

  HttpRequests.startUrl(urlAddrass, new HttpRequests.HttpCallback(){
@Override
public void onSuccess(String string) {
// string is ready to use ;)
}
});
0 0
من اشتباها به جای اینکه اینجا بگم.بالا جواب شما رو دادم. (9 سال پیش)
0 0
robbit جان واقعا ممنونم. لطف کردی. بله کار کرد.خیلی خوبه که با صبر و حوصله دیگران رو راهنمایی میکنی. خدا خیرت بده.بازم ممنون. (9 سال پیش)
0 0
فقط نکته ای رو اضافه کنم که اگر دوستان خواستن استفاده کنن،به یاد داشته باشند.در متد onSuccess بعضی کار ها باید با Handler انجام شه. هنگام اضافه کردن عنصر به یک ArrayList ایراد ترد اصلی داد و وسط برنامه کرش کرد. که با Handler کردن درست شد. (9 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .