我一直在阅读关于这个问题的全天候线索,我想出了一个策略,但却无法使其发挥作用
我有一个listview从sql server获取json数据 此列表视图已具有刷卡刷新功能
我只需要在数据库中插入新行时自动刷新此列表视图。
所以我写了一个获取行数的php文件并用3秒刷新回复它(在php本身上)所以每次我输入php文件时我都得到了我的表的实时行号。
我正在尝试在MainActivity中构建一个函数:
db.php
注意:我不知道如何从我的asynctask中提取字符串以开始用它来操作我的代码。
这就是一般情况,Iv'e添加了主要活动,“外部类”(FetchNumRowAsync)调用php刷卡类和php本身
MainActivity:
int OldNumberOfRows = data from the php file
while(true){
int newNumberOfRows = fetch data again using that php
if(both arent equal) execute refresh command.
}
FetchRowNumAsync:
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
private String TAG = MainActivity.class.getSimpleName();
private String URL = "http://troyka.esy.es/troyka/orders.php";
private SwipeRefreshLayout swipeRefreshLayout;
private ListView listView;
private SwipeListAdapter adapter;
private List<Order> orderList;
// initially offset will be 0, later will be updated while parsing the json
private int offSet = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new FetchRowNumAsync(this).execute("http://troyka.esy.es/numberofrows.php");
listView = (ListView) findViewById(R.id.listView);
//RelativeLayout.LayoutParams layout_description = new RelativeLayout.LayoutParams(50,10);
//Rl.setLayoutParams(layout_description);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
orderList = new ArrayList<>();
adapter = new SwipeListAdapter(this, orderList);
listView.setAdapter(adapter);
swipeRefreshLayout.setOnRefreshListener(this);
/**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
fetchOrders();
}
}
);
}
/**
* This method is called when swipe refresh is pulled down
*/
@Override
public void onRefresh() {
fetchOrders();
}
/**
* Fetching movies json by making http call
*/
private void fetchOrders() {
// showing refresh animation before making http call
swipeRefreshLayout.setRefreshing(true);
// appending offset to url
String url = URL + offSet;
// Volley's json array request object
JsonArrayRequest req = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
if (response.length() > 0) {
// looping through json and adding to order list
for (int i = 0; i < response.length(); i++) {
try {
JSONObject orderObj = response.getJSONObject(i);
int rank = orderObj.getInt("rank");
String title = orderObj.getString("title");
Order m = new Order(rank, title);
orderList.add(0, m);
// updating offset value to highest value
if (rank >= offSet)
offSet = rank;
} catch (JSONException e) {
Log.e(TAG, "JSON Parsing error: " + e.getMessage());
}
}
adapter.notifyDataSetChanged();
}
// stopping swipe refresh
swipeRefreshLayout.setRefreshing(false);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Server Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
// stopping swipe refresh
swipeRefreshLayout.setRefreshing(false);
}
});
// Adding request to request queue
MyApplication.getInstance().addToRequestQueue(req);
}
}
SwipeListAdapter:
public class FetchRowNumAsync extends AsyncTask<String, Void, String> {
private Context mContext;
public FetchRowNumAsync(Context ctx){
this.mContext = ctx;
}
protected String doInBackground(String... urls)
{
String fullString = "";
try{
URL url = new URL(urls[0]);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
fullString += line;
}
reader.close();
}catch(Exception e ){
e.getMessage();
}
return fullString;
}
@Override
protected void onPostExecute(String value){
try{
((OnValueFetchedListener) mContext).onValueFetched(value);
}catch(ClassCastException e){}
}
public interface OnValueFetchedListener{
void onValueFetched(String columns);
}
}
PHP
public class SwipeListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Order> orderList;
private String[] bgColors;
public SwipeListAdapter(Activity activity, List<Order> orderList) {
this.activity = activity;
this.orderList = orderList;
bgColors = activity.getApplicationContext().getResources().getStringArray(R.array.movie_serial_bg);
}
@Override
public int getCount() {
return orderList.size();
}
@Override
public Object getItem(int location) {
return orderList.get(location);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
TextView serial = (TextView) convertView.findViewById(R.id.serial);
TextView title = (TextView) convertView.findViewById(R.id.title);
serial.setText(String.valueOf(orderList.get(position).id));
title.setText(orderList.get(position).title);
String color = bgColors[position % bgColors.length];
serial.setBackgroundColor(Color.parseColor(color));
return convertView;
}
}
答案 0 :(得分:0)
尝试这种方法:
在服务器中创建一个端点,如下所示:
//http://somesite.com/api/data/pull/check
然后,您可以轻松检查此端点是否返回某些值,如 true 或 false ,具体取决于是否有新数据插入数据库。
根据您收到的结果,您可以决定是否通过发出其他HTTP请求来刷新手机上的数据。您总是希望避免向服务器发出不必要的请求 - 请记住用户每次使用他们的数据计划(服务)时都会花钱。
我和上面的评论一样,建议您设置一个时间戳列,您可以检查以便只获取新添加的数据而不是所有内容!
我希望这能让您简单了解如何解决这个问题!祝你好运!
答案 1 :(得分:0)
Android应用程序将不知道您在服务器上的表中添加/更新数据的时间,除非您从应用程序调用脚本并获取数据并在设备中更新。
仅当您的应用已实施这些功能
时这是我对你的建议
从服务器端:
在服务器上的表中创建时间戳字段。用它来更新它 每次进行更改(即更新/添加)时的当前时间戳值 table.and何时调用该脚本在json中发送它 并使你的应用程序将其与数据一起保存在sqlite中。
服务器将比较app每次发布的时间戳 在服务器中为新数据保存了时间戳。
:
在您调用脚本并检查之前,如果添加了新数据,您的应用程序将无法知道。但至少会知道是否收到新数据以及是否刷新你的屏幕
现在来自客户端的脚本调用部分正在执行assynch任务,使用handler来执行每分钟执行assynch类
final Handler timerHandler = new Handler();
Runnable timerRunnable;
timerRunnable = new Runnable() {
@Override
public void run() {
new FetchRowNumAsync(context).execute(url);
timerHandler.postDelayed(timerRunnable, 60000); // run every minute
}
};
并在onDestroy()
中取消注册@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
timerHandler.removeCallbacks(timerRunnable);
}