当我这样做时
WeakEventManager<SystemEvents, EventArgs>
.AddHandler(null, nameof(SystemEvents.DisplaySettingsChanged), OnDisplaySettingsChanged);
我的OnDisplaySettingsChanged
永远不会被调用。但是,如果我通过SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged
使用普通事件订阅,一切正常。
发生了什么事?
答案 0 :(得分:1)
原来是WeakEventManager
的错。当事件被触发时,它意味着source
对于静态事件源将是null
(代码摘录自reference source):
protected void DeliverEvent(object sender, EventArgs args)
{
ListenerList list;
object sourceKey = (sender != null) ? sender : StaticSource;
...
但sender
null
永远不会SystemEvents
。相反,它传递SystemEvents
的私有实例,WeakEventManager
然后假定它是之前不知道的另一个实例,并且不调用处理程序。
以下是我提出的解决方法:
class EventProxy
{
private readonly Action<EventHandler> _subscribe;
private readonly Action<EventHandler> _unsubscribe;
public EventProxy(Action<EventHandler> subscribe, Action<EventHandler> unsubscribe)
{
_subscribe = subscribe;
_unsubscribe = unsubscribe;
}
private EventHandler _event;
public event EventHandler Event
{
add
{
if (_event == null)
_subscribe(OnEvent);
_event += value;
}
remove
{
// ReSharper disable once DelegateSubtraction
_event -= value;
if (_event == null)
_unsubscribe(OnEvent);
}
}
private void OnEvent(object sender, EventArgs args)
{
_event?.Invoke(this, args);
}
}
用法示例:
var proxy = new EventProxy(h => SystemEvents.DisplaySettingsChanged += h, h => SystemEvents.DisplaySettingsChanged -= h);
WeakEventManager<EventProxy, EventArgs>.AddHandler(proxy, nameof(EventProxy.Event), OnDisplaySettingsChanged);
一些解释:
SystemEvents
拥有对EventProxy
的强引用,WeakEventManager
包含对处理程序的弱引用(通过WeakEventManager
)AddHandler
订阅EventProxy
内的事件时,代理订阅原始事件WeakEventManager
充当静态事件和处理程序之间的代理,在原始事件触发时调用处理程序public class B1ITEM1L3 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_b1_item1_l3 );
JSONArray jsonArray=getJSonData( "B1ITEM1DATA.json" );
ArrayList<JSONObject> listItems=getArrayListFromJSONArray(jsonArray);
ListView listV= findViewById(R.id.list_viewL3ITEM1);
ListAdapter adapter = new ListadapterB1ITEM1 (this,R.layout.list_layoutb1item1,R.id.textView,listItems);
listV.setAdapter(adapter);
}
private JSONArray getJSonData(String fileName){
JSONArray jsonArray=null;
try {
InputStream is = getResources().getAssets().open(fileName);
int size = is.available();
byte[] data = new byte[size];
is.read(data);
is.close();
String json = new String(data, "UTF-8");
jsonArray=new JSONArray(json);
}catch (IOException e){
e.printStackTrace();
}catch (JSONException je){
je.printStackTrace();
}
return jsonArray;
}
private ArrayList<JSONObject> getArrayListFromJSONArray(JSONArray jsonArray){
ArrayList<JSONObject> aList= new ArrayList<>();
try {
if (jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
aList.add(jsonArray.getJSONObject(i));
}
}
}catch (JSONException je){je.printStackTrace();}
return aList;
}
public void opencamera(View view) {
Intent intent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE );
startActivity( intent );
} }
最终将运行清理,发现处理程序已死并取消订阅