在非Activity类中显示界面

第一篇博客,跟大家交流一下心得,也作为知识积累

在之前的项目中遇到的问题:在一个mainactivity中需要使用viewpager显示多个界面,而每个界面有自己的业务线程、逻辑与界面的变化控制。犹豫安卓的界面必须在activity对象的ui线程操作,所以他们都需要使用mainactivity的ui线程来显示自己需要的界面效果。

 

为了方便维护我们通常会把不同的业务封装成不同的业务类,这样就给界面的显示带来了更大的麻烦。下面是我针对这个问题的解决方案,并做了相应的封装

 

原理:主要是在业务线程向mainactivity界面线程的消息循环发送一个请求,由mainactivity的ui线程调用业务类中的方法来显示界面。

 

下面贴代码

需要使用到的命令

package com.common;

public class LocalProtocol
{
	//公共命令	
	public class facebase{
		public static final int  FACE_BASE_MASK 				= 0xF0000000;
		public static final int  FACE_BASE_SHOW 				= 0xF0000001;		
	}
}

接口类

package com.common;
public interface SendCommon 
{
	int SendCommand(int cmd, Object packet);
}


重载的activity类,封装了接口函数的操作,这里主要是调用对应的业务工作对象中的SendCommand接口函数获取需要显示的view 。

package com.common;
import android.app.Activity;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class ACFaceCommon extends Activity implements SendCommon {

	public volatile Handler m_Handler = null;
			
	public int SendCommand(int cmd, Object packet) {
		Log.i("tag", "ACFaceCommon - SendCommand");
		switch (cmd & 0xFFFF0000) {
		case LocalProtocol.facebase.FACE_BASE_MASK: {
			switch (cmd) {
			case LocalProtocol.facebase.FACE_BASE_SHOW: {
				if (packet instanceof Message) {				
						((SendCommon) ((Message) packet).obj).SendCommand(cmd,
								packet);
				}
			}
				break;	
			default: {//内部 switch
			}
				break;
			}
		}
			break;
		default: {// top switch
		}
			break;
		}
		return 0;
	}
}

重装的消息队列,将一些默认消息传递给跟他绑定的activity的消息队列

package com.common;
import com.face.ACTest;

import android.content.Context;
import android.os.Handler;
import android.os.Message;

public class HandlerCommon extends Handler{

	
	Context m_context = null;	
	public HandlerCommon(Context context)
	{
		m_context = context;
	}
	
	@Override
	public void handleMessage(Message msg) {
		// TODO Auto-generated method stub
		super.handleMessage(msg);
			switch (msg.what & 0xffff0000) {
			case LocalProtocol.facebase.FACE_BASE_MASK: {
				((SendCommon)m_context).SendCommand(msg.what, msg);
			}
				break;
			}		
	}
}



测试

 

现在写一个业务工作类,拥有自己的工作线程。我们需要在这里面的工作线程写一些比较复杂的流程(必须软件登录、文件或者数据下载),中途还需要显示窗口。

package com.face.data;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.common.LocalProtocol;
import com.common.SendCommon;
import com.face.ACTest;

public class JCTest_1 implements SendCommon{

	Context m_parent = null;
	private Handler m_handle = null; 
	private Thread  m_runthread = null;
	
	
	public int Init(Context context)
	{
		m_parent = context;		
		m_runthread = new Thread(new Runnable() {
			public void run() {

				//业务流程入口
				//开始业务1
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				//显示第一个窗体自定义窗体	
				Log.i("tag", "JCTest_1 - run");							
				Message msg = new Message();
			   	msg.what = LocalProtocol.facebase.FACE_BASE_SHOW;
			   	msg.obj = JCTest_1.this;       
				((ACTest)m_parent).m_Handler.sendMessage(msg);
				
				//使用wait函数或者消息队列等待业务1数据返回
				
				//进入业务2
				//结束
			}
		});
		
		m_runthread.start();
		return 0;
	}
	
	
	public int SendCommand(int cmd, Object packet) {
		Log.i("tag", "JCTest_1 - SendCommand");	
		switch (cmd & 0xFFFF0000) {
		case LocalProtocol.facebase.FACE_BASE_MASK: {
			switch (cmd) {
			case LocalProtocol.facebase.FACE_BASE_SHOW: {
				if (packet instanceof Message) {				
					{						
						//本业务类绑定的activity类的ui线程会调用本函数,在这里显示第一个自定义窗体						
						LinearLayout abort = new LinearLayout(m_parent);
						abort.setOrientation(LinearLayout.VERTICAL);

						TextView text_abort = new TextView(m_parent);
						text_abort.setText("adfasdlfajdkf");
						abort.addView(text_abort);
						
						
						new AlertDialog.Builder(m_parent)
								.setTitle("提示")
								.setView(abort)
								.setPositiveButton("确定",
										new DialogInterface.OnClickListener() {
											public void onClick(DialogInterface dialog,
													int id) {

											}
										})
								.setNegativeButton("取消",
										new DialogInterface.OnClickListener() {
											public void onClick(DialogInterface dialog,
													int id) {
											}
										}).show();
					}
			}
			}
				break;
			default: {//内部 switch
			}
				break;
			}
		}
			break;
		default: {// top switch
		}
			break;
		}
		return 0;
	}

}


 

这里是给业务类JCTest_1绑定的activity类只需要继承于ACFaceCommon就行了

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.common.ACFaceCommon;
import com.common.HandlerCommon;
import com.face.data.JCTest_1;

public class ACTest extends ACFaceCommon {

	JCTest_1 m_test = null;
	
	public volatile Handler m_Handler = new HandlerCommon(this) {
		@Override
		public void handleMessage(Message msg) {			
			super.handleMessage(msg);
			// TODO Auto-generated method stub
	
		}		
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		Log.i("tag", "ACTest - onCreate");
		
		JCTest_1 work1 = new JCTest_1();	
		work1.Init(this);
		
		JCTest_1 work2 = new JCTest_1();	
		work2.Init(this);
		
		JCTest_1 work3 = new JCTest_1();	
		work3.Init(this);
	}

	@Override
	public int SendCommand(int cmd, Object packet) {		
		super.SendCommand(cmd, packet);
		// TODO Auto-generated method stub
		Log.i("tag", "ACTest - SendCommand");	
		
		return 0;
	}			
}

 

 

测试结果:

所有界面的view都是在业务类JCTest_1内生成的,也都是在JCTest_1内发起显示命令的,这样就大大的提高了业务类的编写灵活性
 

第一次写博客,请牛人不要拍砖害羞,有什么不足的还请大家多多指教

 

源码点击打开链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值