Application context and resources
Regardless of how you get access to the resource it will be what relates to the current configuration. So even if you get resource via application context it will provide the correct one after eg. rotation. This is true even if you retain the Resources object (provided by either Context). The configuration resolution happens when you getXXX(). (If you retain the string itself, of course it won't change)private Resources mResources; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); if (getLastNonConfigurationInstance() == null) { mResource = getResources(); } else { mResource = (Resources) getLastNonConfigurationInstance(); // deprecated } final TextView viewById = (TextView)this.findViewById(R.id.text1); viewById.setText(mResource.getString(R.string.foo)); } @Override public Object onRetainNonConfigurationInstance() { return mResource; }
Posting delayed message to Handler of main Thread won't leak the Activity it was created from
The Handler doesn't have a strong reference to the Activity. So if a Handler is created from the main thread (from an Activity eg.), and you don't set explicitly a reference, the Activity can freely be GC-d. Of course the Handler itself will be referenced, so that may be leaked.public class MyActivity extends Activity { private Handler mHandler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("|MQ", "onCreate()"); mHandler = new MyHandler(this); } @Override protected void onResume() { super.onResume(); Log.d("|MQ", "onResume()" + " MyActivity.this: " + MyActivity.this); mHandler.sendEmptyMessageDelayed(1, 30 * 1000); } } private class MyHandler extends Handler { private final WeakReferencemMyActivity; public MyHandler(MyActivity myActivity) { mMyActivity = new WeakReference (myActivity); } @Override public void handleMessage(Message msg) { if (mMyActivity.get() != null) { Log.d("|MQ", "handleMessage()" + " MyActivity.this: " + mMyActivity.get()); } else { Log.d("|MQ", "handleMessage()" + " no MyActivity"); } } }
13:40:43.217 D/|MQ: onCreate()
13:40:43.267 D/|MQ: onResume() MyActivity.this: com.example.broadcastReceive.MyActivity@428d7f38
rotate device
13:40:44.638 D/|MQ: onCreate()
13:40:44.669 D/|MQ: onResume() MyActivity.this: com.example.broadcastReceive.MyActivity@429150c8
rotate device
13:40:46.190 D/|MQ: onCreate()
13:40:46.240 D/|MQ: onResume() MyActivity.this: com.example.broadcastReceive.MyActivity@428b5f08
rotate device
13:40:47.782 D/|MQ: onCreate()
13:40:47.832 D/|MQ: onResume() MyActivity.this: com.example.broadcastReceive.MyActivity@42900c30
13:41:13.279 D/|MQ: handleMessage() no MyActivity
13:41:14.671 D/|MQ: handleMessage() no MyActivity
13:41:16.252 D/|MQ: handleMessage() MyActivity.this: com.example.broadcastReceive.MyActivity@428b5f08
13:41:17.844 D/|MQ: handleMessage() MyActivity.this: com.example.broadcastReceive.MyActivity@42900c30
Anonymous handler leaks the activity
Anonymous class has an implicit reference to the class it was created from. So if such a Handler is created in the onCreate() it will have a reference to the Activity. Then if you postDelayed a Message to the Handler (or a Runnable, which will be wrapped by a Message at the end of the day), the Message will have a reference to the Handler. The main Looper has a reference to the Message, and the Application has a reference to the Looper. And so the Activity is leaked (it won't get GC-d, after onDestroy() till the Message is handled).Example.
Additional info on the different kind of classes.
No comments:
Post a Comment