gpt4 book ai didi

java - 信号量阻塞线程但不会释放它

转载 作者:行者123 更新时间:2023-12-02 11:28:09 25 4
gpt4 key购买 nike

基本上,这里的想法是等到服务器发送访问 token ,否则资源将被旧的 token 加载并且应用程序崩溃。但是在 getAccessToken() 异步请求中获取 token 并使用 waitUntiAccessTokenIsObtained.release() 释放许可后,主线程保持阻塞状态。 waitUntiAccessTokenIsObtained.acquire() 被放置在 MainActivityonCreate 方法中。我错过了什么?

public class MainActivity extends AppCompatActivity {
private BottomNavigationView bottomNavigationView;
private final String IS_FIRST_USE_FLAG = "IS_FIRST_USE_FLAG";
Semaphore waitUntiAccessTokenIsObtained = new Semaphore(0);
private static boolean isFirstUseFlagValue;
SharedPreferences prefs;
ClientCredentialsStore credentialsStore;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = this.getSharedPreferences("com.myapp", Context.MODE_PRIVATE);
handleFlags();

if(this.isFirstUseFlagValue){
registerClient();
getAccessToken();

try {
waitUntiAccessTokenIsObtained.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

setContentView(R.layout.main_screen);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
bottomNavigationView
.setOnNavigationItemSelectedListener
(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.action_item1:
selectedFragment = HomeFragment.newInstance();
break;
case R.id.action_item2:
selectedFragment = CathegoriesListFragment.newInstance();
break;
case R.id.action_item3:
selectedFragment = TestFragment.newInstance();
break;
case R.id.action_item4:
selectedFragment = ItemThreeFragment.newInstance();
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, selectedFragment);
transaction.commit();
return true;
}
});

//Manually displaying the first fragment - one time only
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, HomeFragment.newInstance());
transaction.commit();

//Used to select an item programmatically
//bottomNavigationView.getMenu().getItem(1).setChecked(true);
}

private void handleFlags(){
this.isFirstUseFlagValue = prefs.getBoolean(this.IS_FIRST_USE_FLAG, true);
}

private void registerClient(){
// TODO client registration on server.
String clientNameValue = "clientId";
String clientPasswordValue ="clientSecret";
credentialsStore = new ClientCredentialsStore(getApplicationContext());
credentialsStore.save(clientNameValue, clientPasswordValue);
}

private void getAccessToken(){
// Obtain token from the server.
ClientCredentialsStore credentialsStore = new ClientCredentialsStore(getApplicationContext());
ClientCredentials credentials = credentialsStore.getCredentials();


Call<AccessToken> call = ClientAPI.oAuth2ClientCredentialsGrant(credentials).tokenClient(
ClientAccessTokenRequest.from());

call.enqueue(new Callback<AccessToken>() {
@Override
public void onResponse(Call<AccessToken> call, retrofit2.Response<AccessToken> response) {
AccessToken accessToken = response.body();
TokenStore store = new TokenStore(getApplicationContext());
store.save(accessToken);
waitUntiAccessTokenIsObtained.release();
waitUntiAccessTokenIsObtained.release();
}

@Override
public void onFailure(Call<AccessToken> call, Throwable t) {
Log.e("MainActivity", "could not retrieve access token", t);
}
});
}
}

最佳答案

永远不要在主线程上等待信号量。主线程不得因任何原因而延迟。这样做将使您的应用程序显得无响应(绘制命令将不会被处理)并最终触发看门狗计时器,从而杀死您的应用程序。改为设置加载屏幕,直到您的数据可用。

关于java - 信号量阻塞线程但不会释放它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49467823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com