Java AdvertisingIdClient getAdvertisingIdInfo被主线程阻止
我正在尝试等待AdvertisingIdClient.getAdvertisingIdInfo(活动)的响应,但未成功。在主线程完成之前,此方法不会响应Java AdvertisingIdClient getAdvertisingIdInfo被主线程阻止,java,android,multithreading,google-play-services,Java,Android,Multithreading,Google Play Services,我正在尝试等待AdvertisingIdClient.getAdvertisingIdInfo(活动)的响应,但未成功。在主线程完成之前,此方法不会响应 导入android.app.Activity; 导入android.os.Bundle; 导入android.os.SystemClock; 导入android.util.Log; 导入com.google.android.gms.ads.identifier.advisingiclient; 导入com.google.android.gms.
导入android.app.Activity;
导入android.os.Bundle;
导入android.os.SystemClock;
导入android.util.Log;
导入com.google.android.gms.ads.identifier.advisingiclient;
导入com.google.android.gms.common.ConnectionResult;
导入com.google.android.gms.common.GooglePlayServicesNotAvailableException;
导入com.google.android.gms.common.GooglePlayServicesUtil;
导入java.io.IOException;
公共类MyActivity扩展了活动{
私有活动m_Activity=null;
私有广告客户端.Info m_Info=null;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//使用getAdvertisingIdInfo()启动线程
startGoogleAdvertisingIdRequest(本);
//模拟等待循环,其他应用程序初始化。。。
对于(inti=0;i,在关于AdvertisingIdClient的文献中,它说不要在主线程上使用。它会抛出一个异常。因此,如果您将它放在它自己的线程中,您很可能会没事
要获取google广告ID,不需要在主线程上运行方法getAdvertisingIdInfo
。
我使用异步任务来管理谷歌广告ID的提取
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
String GAID; // this is the String of the Google Ad ID that you'll receive upon onPostExecute
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new GetGAIDTask().execute();
}
private class GetGAIDTask extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... strings) {
AdvertisingIdClient.Info adInfo;
adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(MainActivity.this.getApplicationContext());
if (adInfo.isLimitAdTrackingEnabled()) // check if user has opted out of tracking
return "did not found GAID... sorry";
} catch (IOException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
}
return adInfo.getId();
}
@Override
protected void onPostExecute(String s) {
GAID = s;
}
}
并确保您在Android SDK管理器上有根据文档()更新的“EXTRAS Google Repository”:
不幸的是,在这些情况下,使用com.google.android.gms.iid
不支持创建应用程序范围ID的InstanceID API或系统函数
适当的解决方案,因为该ID可能需要跨多个服务器共享
另一种解决方案是使用广告标识符
可通过getId()从AdvertisingIdClient.Info类获得
方法。您可以使用
getAdvertisingIdInfo(Context)方法,并调用getId()方法
使用标识符。请注意,此方法是阻塞的,因此您应该
不是从主线程调用它;对此的详细解释
方法在此处可用
此外:
public static advisingidclient.Info getadvisingidinfo(上下文
(上下文)
检索用户的广告ID和限制广告跟踪首选项
无法在主线程中调用此方法,因为它可能会阻塞
导致ANRs。如果是,将抛出非法状态异常
在主线程上调用
所以他们说它阻塞了。。。
您需要将此代码放在后台线程中。您所看到的问题,即getAdvertisingIdInfo调用似乎没有足够长的时间来完成,是由您的等待方式和RunnuiThread的工作方式引起的。关键是RunnuiThread将在ui线程上当前运行的代码之后对要运行的代码进行排队,即用于“模拟等待”的休眠调用将让后台线程运行并完成其工作,但设置m_info的最终操作将始终在onCreate完成后排队并执行
一种解决方案是确保从多个线程访问m_信息是安全的,只需在后台线程上分配即可。不需要runOnUiThread。这将消除排队,并允许您的代码在进行最小更改的情况下工作
更好的解决方案是保持runOnUiThread的使用并删除用于等待的睡眠。您需要记住,onCreate中的m_info始终为null,但其他事件可以检查该值是否为非null,并根据需要使用它
在UI线程上运行指定的操作。如果当前线程是UI线程,则立即执行该操作。如果当前线程不是UI线程,则将该操作发布到UI线程的事件队列
你考虑过使用吗?@Fildor:是的,我尝试使用AsyncTask,问题是一样的。然后我猜m_info.getId();
正在阻塞。这里没有调用m_info.getId()(回退到“另一个uuid”,因为m_info为null,因为响应太迟)。你尝试过将对isGooglePlayServicesAvailable的调用放入线程吗?
compile 'com.google.android.gms:play-services-ads:7.8.0'